全新的PDO数据库操作类(仅适用Mysql)
1年前,也差不多刚开博那会,分享过一个pdo的数据库操作类(可参见:http://www.cnblogs.com/hooray/archive/2011/06/30/2094743.html),与其说是类,其实就只是几个封装好的函数,整体略显稚嫩,但也是这么个东西,在公司里也用了1年之久。如今公司规模变大了,产品也日益完善,曾经的那个数据库操作函数虽说使用上没出什么大问题,但为了更显专业,花了1天时间重写了这个,现在,它确实是个类了。
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 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | /** * 作者:胡睿 * 日期:2012/07/21 * 电邮:hooray0905@foxmail.com */ class HRDB{ protected $pdo ; protected $res ; protected $config ; /*构造函数*/ function __construct( $config ){ $this ->Config = $config ; $this ->connect(); } /*数据库连接*/ public function connect(){ $this ->pdo = new PDO( $this ->Config[ 'dsn' ], $this ->Config[ 'name' ], $this ->Config[ 'password' ]); $this ->pdo->query( 'set names utf8;' ); //把结果序列化成stdClass //$this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); //自己写代码捕获Exception $this ->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } /*数据库关闭*/ public function close(){ $this ->pdo = null; } public function query( $sql ){ $res = $this ->pdo->query( $sql ); if ( $res ){ $this ->res = $res ; } } public function exec ( $sql ){ $res = $this ->pdo-> exec ( $sql ); if ( $res ){ $this ->res = $res ; } } public function fetchAll(){ return $this ->res->fetchAll(); } public function fetch(){ return $this ->res->fetch(); } public function fetchColumn(){ return $this ->res->fetchColumn(); } public function lastInsertId(){ return $this ->res->lastInsertId(); } /** * 参数说明 * int $debug 是否开启调试,开启则输出sql语句 * 0 不开启 * 1 开启 * 2 开启并终止程序 * int $mode 返回类型 * 0 返回多条记录 * 1 返回单条记录 * 2 返回行数 * string/array $table 数据库表,两种传值模式 * 普通模式: * 'tb_member, tb_money' * 数组模式: * array('tb_member', 'tb_money') * string/array $fields 需要查询的数据库字段,允许为空,默认为查找全部,两种传值模式 * 普通模式: * 'username, password' * 数组模式: * array('username', 'password') * string/array $sqlwhere 查询条件,允许为空,两种传值模式 * 普通模式: * 'and type = 1 and username like "%os%"' * 数组模式: * array('type = 1', 'username like "%os%"') * string $orderby 排序,默认为id倒序 */ public function select( $debug , $mode , $table , $fields = "*" , $sqlwhere = "" , $orderby = "tbid desc" ){ //参数处理 if ( is_array ( $table )){ $table = implode( ', ' , $table ); } if ( is_array ( $fields )){ $fields = implode( ', ' , $fields ); } if ( is_array ( $sqlwhere )){ $sqlwhere = ' and ' .implode( ' and ' , $sqlwhere ); } //数据库操作 if ( $debug === 0){ if ( $mode === 2){ $this ->query( "select count(tbid) from $table where 1=1 $sqlwhere" ); $return = $this ->fetchColumn(); } else if ( $mode === 1){ $this ->query( "select $fields from $table where 1=1 $sqlwhere order by $orderby" ); $return = $this ->fetch(); } else { $this ->query( "select $fields from $table where 1=1 $sqlwhere order by $orderby" ); $return = $this ->fetchAll(); } return $return ; } else { if ( $mode === 2){ echo "select count(tbid) from $table where 1=1 $sqlwhere" ; } else if ( $mode === 1){ echo "select $fields from $table where 1=1 $sqlwhere order by $orderby" ; } else { echo "select $fields from $table where 1=1 $sqlwhere order by $orderby" ; } if ( $debug === 2){ exit ; } } } /** * 参数说明 * int $debug 是否开启调试,开启则输出sql语句 * 0 不开启 * 1 开启 * 2 开启并终止程序 * int $mode 返回类型 * 0 无返回信息 * 1 返回执行条目数 * 2 返回最后一次插入记录的id * string/array $table 数据库表,两种传值模式 * 普通模式: * 'tb_member, tb_money' * 数组模式: * array('tb_member', 'tb_money') * string/array $set 需要插入的字段及内容,两种传值模式 * 普通模式: * 'username = "test", type = 1, dt = now()' * 数组模式: * array('username = "test"', 'type = 1', 'dt = now()') */ public function insert( $debug , $mode , $table , $set ){ //参数处理 if ( is_array ( $table )){ $table = implode( ', ' , $table ); } if ( is_array ( $set )){ $set = implode( ', ' , $set ); } //数据库操作 if ( $debug === 0){ if ( $mode === 2){ $this ->query( "insert into $table set $set" ); $return = $this ->lastInsertId(); } else if ( $mode === 1){ $this -> exec ( "insert into $table set $set" ); $return = $this ->res; } else { $this ->query( "insert into $table set $set" ); $return = NULL; } return $return ; } else { echo "insert into $table set $set" ; if ( $debug === 2){ exit ; } } } /** * 参数说明 * int $debug 是否开启调试,开启则输出sql语句 * 0 不开启 * 1 开启 * 2 开启并终止程序 * int $mode 返回类型 * 0 无返回信息 * 1 返回执行条目数 * string $table 数据库表,两种传值模式 * 普通模式: * 'tb_member, tb_money' * 数组模式: * array('tb_member', 'tb_money') * string/array $set 需要更新的字段及内容,两种传值模式 * 普通模式: * 'username = "test", type = 1, dt = now()' * 数组模式: * array('username = "test"', 'type = 1', 'dt = now()') * string/array $sqlwhere 修改条件,允许为空,两种传值模式 * 普通模式: * 'and type = 1 and username like "%os%"' * 数组模式: * array('type = 1', 'username like "%os%"') */ public function update( $debug , $mode , $table , $set , $sqlwhere = "" ){ //参数处理 if ( is_array ( $table )){ $table = implode( ', ' , $table ); } if ( is_array ( $set )){ $set = implode( ', ' , $set ); } if ( is_array ( $sqlwhere )){ $sqlwhere = ' and ' .implode( ' and ' , $sqlwhere ); } //数据库操作 if ( $debug === 0){ if ( $mode === 1){ $this -> exec ( "update $table set $set where 1=1 $sqlwhere" ); $return = $this ->res; } else { $this ->query( "update $table set $set where 1=1 $sqlwhere" ); $return = NULL; } return $return ; } else { echo "update $table set $set where 1=1 $sqlwhere" ; if ( $debug === 2){ exit ; } } } /** * 参数说明 * int $debug 是否开启调试,开启则输出sql语句 * 0 不开启 * 1 开启 * 2 开启并终止程序 * int $mode 返回类型 * 0 无返回信息 * 1 返回执行条目数 * string $table 数据库表 * string/array $sqlwhere 删除条件,允许为空,两种传值模式 * 普通模式: * 'and type = 1 and username like "%os%"' * 数组模式: * array('type = 1', 'username like "%os%"') */ public function delete ( $debug , $mode , $table , $sqlwhere = "" ){ //参数处理 if ( is_array ( $sqlwhere )){ $sqlwhere = ' and ' .implode( ' and ' , $sqlwhere ); } //数据库操作 if ( $debug === 0){ if ( $mode === 1){ $this -> exec ( "delete from $table where 1=1 $sqlwhere" ); $return = $this ->res; } else { $this ->query( "delete from $table where 1=1 $sqlwhere" ); $return = NULL; } return $return ; } else { echo "delete from $table where 1=1 $sqlwhere" ; if ( $debug === 2){ exit ; } } } } |
其实使用上,和之前的相差不大,目的就是为了方便移植。
本次重写着重处理了几个问题:
① insert语句太复杂,fields与values对应容易出现误差
我们看下最常见的一句sql插入语句
insert into tb_member (username, type, dt) values ( 'test' , 1, now()) |
在传统模式下,fields和values参数是分开传入的,但却要保证两者参数传入的顺序一致。这很容易导致顺序错乱或者漏传某个参数。
这次已经把问题修改了,采用了mysql独有的insert语法,同样是上面那功能,就可以换成这样的写法
insert into tb_member set username = "test" , type = 1, lastlogindt = now() |
就像update一样,一目了然。
② 部分参数可以用数组代替
比如这样一句sql
delete from tb_member where 1=1 and tbid = 1 and username = "hooray" |
在原先调用方法的时候,需要手动拼装好where条件,这样操作的成本很高,现在完全可以用这种形式
$where = array ( 'tbid = 1' , 'username = "hooray"' ); $db -> delete (1, 0, 'tb_member' , $where ); |
条件再多也不会打乱你的思路。同样,不仅仅是where参数,update里的set也可以以这种形式(具体可参见完整源码)
$set = array ( 'username = "123"' , 'type = 1' , 'lastlogindt = now()' ); $where = array ( 'tbid = 1' ); $db ->update(1, 0, 'tb_member' , $set , $where ); |
③ 可自定义sql语句
有时候,sql过于复杂,导致无法使用类里提供的方法去组装sql语句,这时候就需要一个功能,就是能直接传入我已经组装好的sql语句执行,并返回信息。现在,这功能也有了
$db->query( 'select username, password from tb_member' ); $rs = $db->fetchAll(); |
是不是很像pdo原生态的写法?
④ 支持创建多数据库连接
原先的因为只是数据库操作方法,所以并不支持多数据库连接,在实现上需要复制出2个相同的文件,修改部分变量,操作实属复杂。现在这问题也解决了。
$db_hoorayos_config = array ( 'dsn' => 'mysql:host=localhost;dbname=hoorayos' , 'name' => 'root' , 'password' => 'hooray' ); $db = new HRDB( $db_hoorayos_config ); $db_hoorayos_config2 = array ( 'dsn' => 'mysql:host=localhost;dbname=hoorayos2' , 'name' => 'root' , 'password' => 'hooray' ); $db2 = new HRDB( $db_hoorayos_config2 ); |
这样就能同时创建2个数据库连接,方便处理数据库与数据库交互的情况。
大致新功能就是这么多了,整个代码并不多,欢迎阅读了解。下面是我在编写时写的测试代码,也一并提供上来,方便大家学习。
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 | require_once ( 'global.php' ); require_once ( 'inc/setting.inc.php' ); $db = new HRDB( $db_hoorayos_config ); echo '<hr><b>select测试</b><hr>' ; echo '普通模式,直接字符串传入<br>' ; $rs = $db ->select(1, 0, 'tb_member' , 'username, password' , 'and type = 1 and username like "%os%"' ); echo '<br>数组模式,可传入数组<br>' ; $fields = array ( 'username' , 'password' ); $where = array ( 'type = 1' , 'username like "%os%"' ); $rs = $db ->select(1, 0, 'tb_member' , $fields , $where ); echo '<hr><b>insert测试</b><hr>' ; echo '普通模式,直接字符串传入<br>' ; $db ->insert(1, 0, 'tb_member' , 'username = "test", type = 1, lastlogindt = now()' ); echo '<br>数组模式,可传入数组<br>' ; $set = array ( 'username = "test"' , 'type = 1' , 'lastlogindt = now()' ); $db ->insert(1, 0, 'tb_member' , $set ); echo '<hr><b>update测试</b><hr>' ; echo '普通模式,直接字符串传入<br>' ; $db ->update(1, 0, 'tb_member' , 'username = "123", type = 1, lastlogindt = now()' , 'and tbid = 7' ); echo '<br>数组模式,可传入数组<br>' ; $set = array ( 'username = "123"' , 'type = 1' , 'lastlogindt = now()' ); $where = array ( 'tbid = 1' ); $db ->update(1, 0, 'tb_member' , $set , $where ); echo '<hr><b>delete测试</b><hr>' ; echo '普通模式,直接字符串传入<br>' ; $db -> delete (1, 0, 'tb_member' , 'and tbid = 1 and username = "hooray"' ); echo '<br>数组模式,可传入数组<br>' ; $where = array ( 'tbid = 1' , 'username = "hooray"' ); $db -> delete (1, 0, 'tb_member' , $where ); echo '<hr><b>自定义sql</b><hr>' ; $db ->query( 'select username, password from tb_member' ); $rs = $db ->fetchAll(); var_dump( $rs ); $db ->close(); |
hooray.github.io
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架