本文實例講述了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程序設計有所幫助。