服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - PHP教程 - PHP基于MySQL数据库实现对象持久层的方法

PHP基于MySQL数据库实现对象持久层的方法

2020-09-29 15:36RobinTang PHP教程

这篇文章主要介绍了PHP基于MySQL数据库实现对象持久层的方法,实例分析了php实现持久层的相关技巧,需要的朋友可以参考下

本文实例讲述了PHP基于MySQL数据库实现对象持久层的方法。分享给大家供大家参考。具体如下:

心血来潮,做了一下PHP的对象到数据库的简单持久层。

不常用PHP,对PHP也不熟,关于PHP反射的大部分内容都是现学的。

目前功能比较弱,只是完成一些简单的工作,对象之间的关系还没法映射,并且对象的成员只能支持string或者integer两种类型的。

成员变量的值也没有转义一下。。。

下面就贴一下代码:

首先是数据库的相关定义,该文件定义了数据库的连接属性:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
/*
 * Filename: config.php
 * Created on 2012-9-29
 * Created by RobinTang
 * To change the template for this generated file go to
 * Window - Preferences - PHPeclipse - PHP - Code Templates
 */
  // About database
  define('DBHOST', 'localhost'); // 数据库服务器
  define('DBNAME', 'db_wdid'); // 数据库名称
  define('DBUSER', 'root'); // 登陆用户名
  define('DBPSWD', 'trb'); // 登录密码
?>

下面是数据库访问的简单封装:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<?php
/*
 * Filename: database.php
 * Created on 2012-9-29
 * Created by RobinTang
 * To change the template for this generated file go to
 * Window - Preferences - PHPeclipse - PHP - Code Templates
 */
  include_once("config.php");
  $debug = false;
  $g_out = false;
  function out($s){
    global $g_out;
    $g_out .= $s;
    $g_out .= "\r\n";
  }
  function db_openconnect(){
    $con = mysql_connect(DBHOST, DBUSER, DBPSWD);
     
    if(!mysql_set_charset("utf8", $con)){
      out("set mysql encoding fail");
    }
    if (!$con){
      out('Could not connect: ' . mysql_error());
    }
    else{
      if(!mysql_select_db(DBNAME, $con)){
        $dbn = DBNAME;
        out("Could select database '$dbn' : " . mysql_error());
      }
      $sql = "set time_zone = '+8:00';";
      if(!db_onlyquery($sql, $con)){
        out("select timezone fail!" . mysql_error());
      }
    }
    return $con;
  }
  function db_colseconnect($con){
    mysql_close($con);
  }
  function db_onlyquery($sql, $con){
    $r = mysql_query($sql, $con);
    if(!$r){
      out("query '$sql' :fail");
      return false;
    }
    else{
      return $r;
    }
  }
  function db_query($sql){
    $con = db_openconnect();
    $r = db_onlyquery($sql, $con);
    $res = false;
    if($r){
      $res = true;
    }
    db_colseconnect($con);
    return $r;
  }
  function db_query_effect_rows($sql){
    $con = db_openconnect();
    $r = db_onlyquery($sql, $con);
    $res = false;
    if($r){
      $res = mysql_affected_rows($con);
      if($res==0){
        $res = -1;
      }
    }
    else{
      $res = false;
    }
    db_colseconnect($con);
    return $res;
  }
  function db_getresult($sql){
    $con = db_openconnect();
    $r = db_onlyquery($sql, $con);
    $res = false;
    if($r && $arr = mysql_fetch_row($r)){
      $res = $arr[0];
    }
    db_colseconnect($con);
    return $res;
  }
  function db_getarray($sql){
    $con = db_openconnect();
    $r = db_onlyquery($sql, $con);
    $ret = false;
    if($r){
      $row = false;
      $len = 0;
      $ret = Array();
      $i = 0;
      while($arr = mysql_fetch_row($r)){
        if($row == false || $len==0){
          $row = Array();
          $len = count($arr);
          for($i=0;$i<$len;++$i){
            $key = mysql_field_name($r, $i);
            array_push($row, $key);
          }
        }
        $itm = Array();
        for($i=0;$i<$len;++$i){
          $itm[$row[$i]]=$arr[$i];
        }
        array_push($ret, $itm);
      }
    }
    db_colseconnect($con);
    return $ret;
  }
?>

其实上面的两个文件都是之前写好的,持久层的东西是下面的:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
<?php
/*
 * Filename: sinorm.php
 * Created on 2012-11-4
 * Created by RobinTang
 * To change the template for this generated file go to
 * Window - Preferences - PHPeclipse - PHP - Code Templates
 */
  include_once("database.php");
   
  function SinORM_ExecSql($sql) {
    return db_query($sql);
  }
  function SinORM_ExecArray($sql) {
    return db_getarray($sql);
  }
  function SinORM_ExecResult($sql){
    return db_getresult($sql);
  }
  function SinORM_GetClassPropertys($class) {
    $r = new ReflectionClass($class);
    if (!$r->hasProperty('tablename')) {
      throw new Exception("Class '$class' has no [tablename] property");
    }
    $table = $r->getStaticPropertyValue('tablename');
    if (!$r->hasProperty('id')) {
      throw new Exception("Class '$class' has no [id] property");
    }
    $mpts = Array ();
    $pts = $r->getProperties(ReflectionProperty :: IS_PUBLIC);
    foreach ($pts as $pt) {
      if (!$pt->isStatic()) {
        array_push($mpts, $pt);
      }
    }
    return Array (
      $table,
      $mpts
    );
  }
  function SinORM_GetPropertyString($pts, $class, $obj = false, $noid = false) {
    if (is_null($pts)) {
      list ($tb, $pts) = SinORM_GetClassPropertys($class);
    }
    $s = false;
    $v = false;
    $l = false;
    foreach ($pts as $pt) {
      $name = $pt->name;
      if ($noid == false || $name != 'id') {
        if ($l) {
          $s = $s . ',';
        }
        $s = $s . $name;
   
        if ($obj) {
          if ($l) {
            $v = $v . ',';
          }
          $val = $pt->getValue($obj);
          if (is_null($val))
            $v = $v . 'null';
          if (is_string($val))
            $v = $v . "'$val'";
          else
            $v = $v . $val;
        }
        $l = true;
      }
    }
    return Array (
      $s,
      $v
    );
  }
  function SinORM_GetTableName($class){
    $r = new ReflectionClass($class);
    if (!$r->hasProperty('tablename')) {
      throw new Exception("Class '$class' has no [tablename] property");
    }
    $table = $r->getStaticPropertyValue('tablename');
    if (!$r->hasProperty('id')) {
      throw new Exception("Class '$class' has no [id] property");
    }
    return $table;
  }
  function SinORM_ResetORM($class) {
    list ($tb, $pts) = SinORM_GetClassPropertys($class);
    $sql = "CREATE TABLE `$tb` (`id` int NOT NULL AUTO_INCREMENT";
    $r = new ReflectionClass($class);
    $obj = $r->newInstance();
    foreach ($pts as $pt) {
      $val = $pt->getValue($obj);
      $name = $pt->name;
      if ($name != 'id') {
        $sql = $sql . ',';
      } else {
        continue;
      }
      if (is_null($val))
        throw new Exception($class . '->' . "name must have a default value");
      if (is_string($val))
        $sql = $sql . "`$name` text NULL";
      else
        $sql = $sql . "`$name` int NULL";
    }
    $sql = $sql . ",PRIMARY KEY (`id`));";
    $dsql = "DROP TABLE IF EXISTS `$tb`;";
    return SinORM_ExecSql($dsql) && SinORM_ExecSql($sql);
  }
  function SinORM_SaveObject($obj) {
    $class = get_class($obj);
    list ($tb, $pts) = SinORM_GetClassPropertys($class);
    list ($names, $vals) = SinORM_GetPropertyString($pts, $class, $obj, true);
    $sql = "INSERT INTO `$tb`($names) values($vals)";
    if(SinORM_ExecSql($sql)){
      $q = "SELECT `id` FROM `$tb` ORDER BY `id` DESC LIMIT 1;";
      $id = SinORM_ExecResult($q);
      if($id){
        $obj->id = $id;
      }
    }
    return false;
  }
  function SinORM_GetObjects($class) {
    list ($tb, $pts) = SinORM_GetClassPropertys($class);
    $sql = "SELECT * from `$tb`;";
    $ary = SinORM_ExecArray($sql);
    $res = false;
    if (is_array($ary)) {
      $res = Array ();
      $ref = new ReflectionClass($class);
      foreach ($ary as $a) {
        $obj = $ref->newInstance();
        foreach ($pts as $pt) {
          $name = $pt->name;
          $olv = $pt->getValue($obj);
          $val = $a[$name];
          if (is_string($olv))
            $pt->setValue($obj, $val);
          else
            $pt->setValue($obj, intval($val));
        }
        array_push($res, $obj);
      }
    } else {
      echo 'no';
    }
    return $res;
  }
  function SinORM_GetObject($class, $id) {
    list ($tb, $pts) = SinORM_GetClassPropertys($class);
    $sql = "SELECT * from `$tb` where `id`=$id;";
    $ary = SinORM_ExecArray($sql);
    $res = null;
    if (is_array($ary) && count($ary) > 0) {
      $res = Array ();
      $ref = new ReflectionClass($class);
      $a = $ary[0];
      $obj = $ref->newInstance();
      foreach ($pts as $pt) {
        $name = $pt->name;
        $olv = $pt->getValue($obj);
        $val = $a[$name];
        if (is_string($olv))
          $pt->setValue($obj, $val);
        else
          $pt->setValue($obj, intval($val));
      }
      return $obj;
    }
    return null;
  }
  function SinORM_Update($obj) {
    $class = get_class($obj);
    list ($tb, $pts) = SinORM_GetClassPropertys($class);
    $sql = "UPDATE `$tb` SET ";
    $l = false;
    foreach ($pts as $pt) {
      $name = $pt->name;
      $val = $pt->getValue($obj);
      if ($name == 'id')
        continue;
      if ($l)
        $sql = $sql . ',';
      if (is_string($val))
        $sql = $sql . "$name='$val'";
      else
        $sql = $sql . "$name=$val";
      $l = true;
    }
    $sql = $sql . " WHERE `id`=$obj->id;";
    return SinORM_ExecSql($sql);
  }
  function SinORM_SaveOrUpdate($obj) {
    if (SinORM_GetObject(get_class($obj), $obj->id) == null) {
      SinORM_SaveObject($obj);
    } else {
      SinORM_Update($obj);
    }
  }
  function SinORM_DeleteObject($obj){
    $class = get_class($obj);
    $tb = SinORM_GetTableName($class);
    $sql = "DELETE FROM `$tb` WHERE `id`=$obj->id;";
    return SinORM_ExecSql($sql);
  }
  function SinORM_DeleteAll($class){
    $tb = SinORM_GetTableName($class);
    $sql = "DELETE FROM `$tb`;";
    return SinORM_ExecSql($sql);
  }
?>

下面是使用的例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
/*
 * Filename: demo.php
 * Created on 2012-11-4
 * Created by RobinTang
 * To change the template for this generated file go to
 * Window - Preferences - PHPeclipse - PHP - Code Templates
 */
  include_once("sinorm.php");
  // 下面是一个持久对象的类的定义
  // 每个持久对象类都必须有一个叫做$tablename静态成员,它表示数据库中存储对象的表名
  // 类的每个成员都必须初始化,也就是必须给它一个初始值
  // 成员变量只能为字符串或者整型,而且请定义成public的,只有public的成员变量会被映射
  class User{
    public static $tablename = 't_user'// 静态变量,对象的表名,必须的
    public $id = 0; // 对象ID,对应表中的主键,必须的,而且必须初始化为0
     
    public $name = ''; // 姓名,必须初始化
    public $age = 0; // 年龄,必须初始化
    public $email = ''; // 必须初始化 
  }
   
  // 注意:下面的语句一定要在定义好类之后运行一下,修改了类也需要运行一下,它完成创建表的工作
  // SinORM_ResetORM('User'); // 这一句只是一开始执行一次,执行之后就会自动在数据库中建立User对应的表
   
  $user1 = new User();  // 创建一个对象
  $user1->name = 'TRB';
  $user1->age = 22;
  $user1->email = 'trbbadboy@qq.com';
  SinORM_SaveObject($user1); // 把对象保存到数据库中
   
  // 保存之后会自动给id的
  $id = $user1->id;
  echo $id . '<br/>';
    
  $user2 = SinORM_GetObject('User', $id); // 通过ID从数据库创建一个对象
  echo $user2->name . '<br/>';
   
  $user1->name = 'trb'; // 改变一下
  SinORM_Update($user1); // 更新到数据库
   
  $user3 = SinORM_GetObject('User', $id); // 重新读出
  echo $user3->name . '<br/>';
?>

希望本文所述对大家的php程序设计有所帮助。

延伸 · 阅读

精彩推荐