php设计模式之数据对象映射模式
所谓的数据对象映射模式,就是用对象与数据库中的字段一一对应,这样操作对象就可以操作数据实体。也就是我们常用的ORM。下面我来展示一个建议的php的ORM,主要参考了一些TP框架的思路,很简易。还有好多东西待完善,给那些想研究ORM的同学提供一些思路吧。
1 <?php 2 /** 3 * author: NickBai 4 * createTime: 2016/11/28 0028 下午 4:00 5 */ 6 class MyOrm implements ArrayAccess 7 { 8 public $host = '127.0.0.1'; //数据库地址 9 public $dbname = 'test'; //数据库名 10 public $user = 'root'; //数据库用户名 11 public $pwd = 'root'; //数据库密码 12 public $port = '3306'; //数据库端口 13 public $charset = 'utf8'; //数据库编码 14 private $conn = null; //数据库链接资源 15 private $alias = []; //记录全局的语句参数 16 private $sql; //存储最后一条sql 17 18 public function __construct() 19 { 20 if( is_null( $this->conn ) ){ 21 22 $dsn = "mysql:host=$this->host;dbname=$this->dbname;charset=$this->charset;port=$this->port"; 23 $this->conn = new PDO( $dsn, $this->user, $this->pwd ); 24 } 25 } 26 27 //field语句 28 public function field( $field ) 29 { 30 if( !is_string( $field ) ){ 31 throw new exception("field语句的参数必须为字符串"); 32 } 33 34 $this->alias['field'] = $field; 35 return $this; 36 } 37 38 //table语句 39 public function table( $table ) 40 { 41 if( !is_string( $table ) ){ 42 throw new exception("table语句的参数必须为字符串"); 43 } 44 45 $this->alias['table'] = $table; 46 return $this; 47 } 48 49 //where语句 50 public function where( $where ) 51 { 52 $this->alias['where'] = ''; 53 if( is_array( $where ) ){ 54 55 foreach( $where as $key=>$vo ){ 56 $this->alias['where'] .= " `$key`" . ' = ' . $vo . ' and '; 57 } 58 $this->alias['where'] = rtrim( $this->alias['where'], 'and ' ); 59 60 }else if( is_string( $where ) ){ 61 62 $this->alias['where'] = $where; 63 }else{ 64 65 throw new exception("where语句的参数必须为数组或字符串"); 66 } 67 68 return $this; 69 } 70 71 //limit语句 72 public function limit( $limit ) 73 { 74 $this->alias['limit'] = ''; 75 if( is_numeric( $limit ) ){ 76 $this->alias['limit'] = '0,' . $limit; 77 }else if( is_string( $limit ) ){ 78 $this->alias['limit'] = $limit; 79 }else{ 80 throw new exception("limit语句的参数必须为数字或字符串"); 81 } 82 83 return $this; 84 } 85 86 //order语句 87 public function order( $order ) 88 { 89 if( !is_string( $order ) ){ 90 throw new exception("order语句的参数必须为字符串"); 91 } 92 93 $this->alias['order'] = $order; 94 return $this; 95 } 96 97 //group语句 98 public function group( $group ) 99 { 100 if( !is_string( $group ) ){ 101 throw new exception("group语句的参数必须为字符串"); 102 } 103 104 $this->alias['group'] = $group; 105 return $this; 106 } 107 108 //解析查询sql语句 109 public function ParseSelectSql() 110 { 111 $this->sql = 'select *'; 112 if( !empty( $this->alias['field'] ) ){ 113 $this->sql = str_replace( '*', $this->alias['field'], $this->sql ); 114 } 115 116 if( empty( $this->alias['table'] ) ){ 117 throw new exception("请用table子句设置查询表"); 118 }else{ 119 120 $this->sql .= ' from ' . $this->alias['table']; 121 } 122 123 if( !empty( $this->alias['where'] ) ){ 124 $this->sql .= ' where ' . $this->alias['where']; 125 } 126 127 if( !empty( $this->alias['group'] ) ){ 128 $this->sql .= ' group by ' . $this->alias['group']; 129 } 130 131 if( !empty( $this->alias['order'] ) ){ 132 $this->sql .= ' order by ' . $this->alias['order']; 133 } 134 135 if( !empty( $this->alias['limit'] ) ){ 136 $this->sql .= ' limit ' . $this->alias['limit']; 137 } 138 139 } 140 141 //解析添加sql语句 142 public function ParseAddSql() 143 { 144 $this->sql = 'insert into '; 145 if( empty( $this->alias['table'] ) ){ 146 throw new exception("请用table子句设置添加表"); 147 }else{ 148 149 $this->sql .= $this->alias['table'] . ' set '; 150 } 151 152 return $this->sql; 153 } 154 155 //解析更新sql语句 156 public function ParseUpdateSql() 157 { 158 $this->sql = 'update '; 159 if( empty( $this->alias['table'] ) ){ 160 throw new exception("请用table子句设置修改表"); 161 }else{ 162 163 $this->sql .= $this->alias['table'] . ' set '; 164 } 165 166 if( empty( $this->alias['where'] ) ){ 167 throw new exception("更新语句必须有where子句指定条件"); 168 } 169 170 return $this->sql; 171 } 172 173 //解析删除sql语句 174 public function ParseDeleteSql() 175 { 176 $this->sql = 'delete from '; 177 if( empty( $this->alias['table'] ) ){ 178 throw new exception("请用table子句设置删除表"); 179 }else{ 180 181 $this->sql .= $this->alias['table']; 182 } 183 184 if( empty( $this->alias['where'] ) ){ 185 throw new exception("删除语句必须有where子句指定条件"); 186 } 187 188 $this->sql .= ' where ' . $this->alias['where']; 189 190 return $this->sql; 191 } 192 193 194 //查询语句 195 public function select() 196 { 197 $this->ParseSelectSql(); 198 $row = $this->conn->query( $this->sql )->fetchAll( PDO::FETCH_ASSOC ); 199 $result = []; 200 201 foreach( $row as $key=>$vo ){ 202 203 $arrObj = clone $this; //clone当前对象防止对this对象造成污染 204 $arrObj->data = $vo; 205 $result[$key] = $arrObj; 206 unset( $arrObj ); 207 } 208 209 return $result; 210 } 211 212 //查询一条 213 public function find() 214 { 215 $this->ParseSelectSql(); 216 $row = $this->conn->query( $this->sql )->fetch( PDO::FETCH_ASSOC ); 217 218 $arrObj = clone $this; //clone当前对象防止对this对象造成污染 219 $arrObj->data = $row; 220 $result = $arrObj; 221 unset( $arrObj ); 222 223 return $result; 224 } 225 226 //添加数据 227 public function add( $data ) 228 { 229 if( !is_array( $data ) ){ 230 throw new exception("添加数据add方法参数必须为数组"); 231 } 232 233 $this->ParseAddSql(); 234 foreach( $data as $key=>$vo ){ 235 $this->sql .= " `{$key}` = '" . $vo . "',"; 236 } 237 238 $this->conn->exec( rtrim( $this->sql, ',' ) ); 239 return $this->conn->lastInsertId(); 240 } 241 242 //更新语句 243 public function update( $data ) 244 { 245 if( !is_array( $data ) ){ 246 throw new exception("更新数据update方法参数必须为数组"); 247 } 248 249 $this->ParseUpdateSql(); 250 foreach( $data as $key=>$vo ){ 251 $this->sql .= " `{$key}` = '" . $vo . "',"; 252 } 253 254 $this->sql = rtrim( $this->sql, ',' ) . ' where ' . $this->alias['where']; 255 return $this->conn->exec( $this->sql ); 256 257 } 258 259 //删除语句 260 public function delete() 261 { 262 $this->ParseDeleteSql(); 263 return $this->conn->exec( $this->sql ); 264 } 265 266 //获取查询数据 267 public function getData() 268 { 269 return $this->data; 270 } 271 272 //获取最后一次执行的sql语句 273 public function getLastSql() 274 { 275 return $this->sql; 276 } 277 278 public function __get($name) 279 { 280 return $this->getData()[$name]; 281 } 282 283 public function offsetExists($offset) 284 { 285 if( !isset( $this->getData()[$offset] ) ){ 286 return NULL; 287 } 288 } 289 290 public function offsetGet($offset) 291 { 292 return $this->getData()[$offset]; 293 } 294 295 public function offsetSet($offset, $value) 296 { 297 return $this->data[$offset] = $value; 298 } 299 300 public function offsetUnset($offset) 301 { 302 unset( $this->data[$offset] ); 303 } 304 }
我们怎么使用它呢?首先实例化。
1 <?php 2 $orm = new MyOrm();
我本地演示的表机构和数据如下:
接下来展示一下它有那些用法,熟悉TP的同学肯定感觉很熟悉。
1 <?php 2 //查询语句 3 $res = $orm->table('user')->order('id desc')->select(); 4 $res = $orm->table('user')->where("name='test'")->order('id desc')->select(); 5 $res = $orm->table('user')->where(['id' => 1])->order('id desc')->find(); 6 $res = $orm->table('user')->where("age > 20")->group('group by name')->order('id desc')->limit(2)->select(); 7 $res = $orm->table('user')->where("age > 20")->group('group by name')->order('id desc')->limit('2,2')->select(); 8 9 //你可以这样处理数据 10 foreach( $res as $key=>$vo ){ 11 echo $vo->name . '<br/>'; 12 } 13 //也可以这样处理 14 foreach( $res as $key=>$vo ){ 15 echo $vo['name'] . '<br/>'; 16 } 17 //还可以这样 18 foreach( $res as $key=>$vo ){ 19 print_r( $vo->getData() ) . '<br/>'; 20 } 21 22 //添加数据 23 $data = [ 24 'name' => 'test1', 25 'age' => 20, 26 'password' => '21232f297a57a5a743894a0e4a801fc3', 27 'salt' => 'domain' 28 ]; 29 $res = $orm->table('user')->add( $data ); 30 31 //更新数据 32 $res = $orm->table('user')->where(['id' => 4])->update( ['name' => 'sdfdsfdsd', 'salt' => '111'] ); 33 34 //删除数据 35 $res = $orm->table('user')->where(['id' => 7, 'id' => 6])->delete(); 36 37 //获取执行的sql语句 38 echo $orm->getLastSql(); 39 40 var_dump($res);
声明:本文内容仅是本人学习的记录,不保证在项目中可用,若引用此代码导致了严重后果,本人不承担任何法律责任。