PHP用PDO如何封装简单易用的DB类详解


Posted in PHP onJuly 30, 2017

前言

PDO扩展为PHP访问数据库定义了一个轻量级的、一致性的接口,它提供了一个数据访问抽象层,这样,无论使用什么数据库,都可以通过一致的函数执行查询和获取数据。PDO随PHP5.1发行,在PHP5.0的PECL扩展中也可以使用。

我个人理解:PDO是一个抽象类,为我们提供访问数据的接口方法,下面这篇将给大家介绍关于PHP如何利用PDO封装简单易用的DB类,下面话不多说,来一起看看详细的介绍:

使用

创建测试库和表

create database db_test;
CREATE TABLE `user` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `name` char(11) NOT NULL,
 `created_at` int(10) unsigned NOT NULL,
 PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `user` VALUES ('1', 'wang', '1501109027');
INSERT INTO `user` VALUES ('2', 'meng', '1501109026');
INSERT INTO `user` VALUES ('3', 'liu', '1501009027');
INSERT INTO `user` VALUES ('4', 'yuan', '1500109027');

代码测试

require __DIR__ . '/DB.php';
$db = new DB();
$db->__setup([
 'dsn'=>'mysql:dbname=db_test;host=localhost',
 'username'=>'root',
 'password'=>'******',
 'charset'=>'utf8'
]);


$user = $db->fetch('SELECT * FROM user where id = :id', ['id' => 1]);
echo $user['name'];
echo "\n";

$insertId = $db->insert('user', ['name' => 'salamander', 'created_at' => time()]);
echo "insert user {$insertId}\n";
$users = $db->fetchAll('SELECT * FROM user');
foreach ($users as $item) {
 echo "user {$item['id']} is {$item['name']} \n";
}

运行结果

PHP用PDO如何封装简单易用的DB类详解

DB工具类

<?php
/**
 * User: Salamander
 * Date: 2016/9/2
 * Time: 9:16
 */

class DB
{
 private $dsn;
 private $sth;
 private $dbh;
 private $user;
 private $charset;
 private $password;

 public $lastSQL = '';

 public function __setup($config = array())
 {
  $this->dsn = $config['dsn'];
  $this->user = $config['username'];
  $this->password = $config['password'];
  $this->charset = $config['charset'];
  $this->connect();
 }

 private function connect()
 {
  if(!$this->dbh){
   $options = array(
    \PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . $this->charset,
   );
   $this->dbh = new \PDO($this->dsn, $this->user,
    $this->password, $options);
  }
 }

 public function beginTransaction()
 {
  return $this->dbh->beginTransaction();
 }

 public function inTransaction()
 {
  return $this->dbh->inTransaction();
 }

 public function rollBack()
 {
  return $this->dbh->rollBack();
 }

 public function commit()
 {
  return $this->dbh->commit();
 }

 function watchException($execute_state)
 {
  if(!$execute_state){
   throw new MySQLException("SQL: {$this->lastSQL}\n".$this->sth->errorInfo()[2], intval($this->sth->errorCode()));
  }
 }

 public function fetchAll($sql, $parameters=[])
 {
  $result = [];
  $this->lastSQL = $sql;
  $this->sth = $this->dbh->prepare($sql);
  $this->watchException($this->sth->execute($parameters));
  while($result[] = $this->sth->fetch(\PDO::FETCH_ASSOC)){ }
  array_pop($result);
  return $result;
 }

 public function fetchColumnAll($sql, $parameters=[], $position=0)
 {
  $result = [];
  $this->lastSQL = $sql;
  $this->sth = $this->dbh->prepare($sql);
  $this->watchException($this->sth->execute($parameters));
  while($result[] = $this->sth->fetch(\PDO::FETCH_COLUMN, $position)){ }
  array_pop($result);
  return $result;
 }

 public function exists($sql, $parameters=[])
 {
  $this->lastSQL = $sql;
  $data = $this->fetch($sql, $parameters);
  return !empty($data);
 }

 public function query($sql, $parameters=[])
 {
  $this->lastSQL = $sql;
  $this->sth = $this->dbh->prepare($sql);
  $this->watchException($this->sth->execute($parameters));
  return $this->sth->rowCount();
 }

 public function fetch($sql, $parameters=[], $type=\PDO::FETCH_ASSOC)
 {
  $this->lastSQL = $sql;
  $this->sth = $this->dbh->prepare($sql);
  $this->watchException($this->sth->execute($parameters));
  return $this->sth->fetch($type);
 }

 public function fetchColumn($sql, $parameters=[], $position=0)
 {
  $this->lastSQL = $sql;
  $this->sth = $this->dbh->prepare($sql);
  $this->watchException($this->sth->execute($parameters));
  return $this->sth->fetch(\PDO::FETCH_COLUMN, $position);
 }

 public function update($table, $parameters=[], $condition=[])
 {
  $table = $this->format_table_name($table);
  $sql = "UPDATE $table SET ";
  $fields = [];
  $pdo_parameters = [];
  foreach ( $parameters as $field=>$value){
   $fields[] = '`'.$field.'`=:field_'.$field;
   $pdo_parameters['field_'.$field] = $value;
  }
  $sql .= implode(',', $fields);
  $fields = [];
  $where = '';
  if(is_string($condition)) {
   $where = $condition;
  } else if(is_array($condition)) {
   foreach($condition as $field=>$value){
    $parameters[$field] = $value;
    $fields[] = '`'.$field.'`=:condition_'.$field;
    $pdo_parameters['condition_'.$field] = $value;
   }
   $where = implode(' AND ', $fields);
  }
  if(!empty($where)) {
   $sql .= ' WHERE '.$where;
  }
  return $this->query($sql, $pdo_parameters);
 }

 public function insert($table, $parameters=[])
 {
  $table = $this->format_table_name($table);
  $sql = "INSERT INTO $table";
  $fields = [];
  $placeholder = [];
  foreach ( $parameters as $field=>$value){
   $placeholder[] = ':'.$field;
   $fields[] = '`'.$field.'`';
  }
  $sql .= '('.implode(",", $fields).') VALUES ('.implode(",", $placeholder).')';

  $this->lastSQL = $sql;
  $this->sth = $this->dbh->prepare($sql);
  $this->watchException($this->sth->execute($parameters));
  $id = $this->dbh->lastInsertId();
  if(empty($id)) {
   return $this->sth->rowCount();
  } else {
   return $id;
  }
 }

 public function errorInfo()
 {
  return $this->sth->errorInfo();
 }

 protected function format_table_name($table)
 {
  $parts = explode(".", $table, 2);

  if(count($parts) > 1) {
   $table = $parts[0].".`{$parts[1]}`";
  } else {
   $table = "`$table`";
  }
  return $table;
 }

 function errorCode()
 {
  return $this->sth->errorCode();
 }
}

class MySQLException extends \Exception { }

框架中使用建议

在框架中使用DB类,用单例模式或者用依赖容器来管理较好。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持

PHP 相关文章推荐
PHP ajax 分页类代码
Nov 13 PHP
php中利用post传递字符串重定向的实现代码
Apr 21 PHP
php curl的深入解析
Jun 02 PHP
php后台如何避免用户直接进入方法实例
Oct 15 PHP
PHP循环输出指定目录下的所有文件和文件夹路径例子(简单实用)
May 10 PHP
PHP获取中英混合字符串长度的方法
Jun 07 PHP
ThinkPHP3.1新特性之命名范围的使用
Jun 19 PHP
ThinkPHP访问不存在的模块跳转到404页面的方法
Jun 19 PHP
php采用ajax数据提交post与post常见方法总结
Nov 10 PHP
PHP开发中csrf攻击的简单演示和防范
May 07 PHP
laravel5.4生成验证码的实例讲解
Aug 05 PHP
PHP中in_array的隐式转换的解决方法
Mar 06 PHP
详解PHP防止直接访问.php 文件的实现方法
Jul 28 #PHP
php简单实现单态设计模式的方法分析
Jul 28 #PHP
[原创]PHP实现SQL语句格式化功能的方法
Jul 28 #PHP
使用php自动备份数据库表的实现方法
Jul 28 #PHP
PHP自定义函数判断是否为Get、Post及Ajax提交的方法
Jul 27 #PHP
PHP 7安装使用体验之性能大提升,兼容性强,扩展支持不够(升级PHP要谨慎)
Jul 27 #PHP
laravel 5.4中实现无限级分类的方法示例
Jul 27 #PHP
You might like
收音机指标测试方法及仪器
2021/03/01 无线电
php array_push()数组函数:将一个或多个单元压入数组的末尾(入栈)
2011/07/12 PHP
ThinkPHP实现静态缓存和动态缓存示例代码
2017/05/02 PHP
laravel框架使用极光推送消息操作示例
2020/02/15 PHP
使用隐藏的new来创建对象
2011/03/29 Javascript
Jquery获取和修改img的src值的方法
2014/02/17 Javascript
js+cookies实现悬浮购物车的方法
2015/05/25 Javascript
javascript日期格式化方法小结
2015/12/17 Javascript
jquery调整表格行tr上下顺序实例讲解
2016/01/09 Javascript
基于javascript实现表格的简单操作
2016/05/21 Javascript
关于vue.js组件数据流的问题
2017/07/26 Javascript
jquery.picsign图片标注组件实例详解
2018/02/02 jQuery
vue中倒计时组件的实例代码
2018/07/06 Javascript
vue 循环加载数据并获取第一条记录的方法
2018/09/26 Javascript
vue使用laydate时间插件的方法
2018/11/14 Javascript
使用webpack编译es6代码的方法步骤
2019/04/28 Javascript
jQuery 查找元素操作实例小结
2019/10/02 jQuery
Vue axios 将传递的json数据转为form data的例子
2019/10/29 Javascript
[03:20]次级联赛厮杀超职业 现超级兵对拆世纪大战
2014/10/30 DOTA
Python Requests 基础入门
2016/04/07 Python
Python中的命令行参数解析工具之docopt详解
2017/03/27 Python
Django中间件工作流程及写法实例代码
2018/02/06 Python
python字典值排序并取出前n个key值的方法
2018/10/17 Python
python实现逆滤波与维纳滤波示例
2020/02/26 Python
python3发送request请求及查看返回结果实例
2020/04/30 Python
倩碧香港官方网站:Clinique香港
2017/11/13 全球购物
Carter’s OshKosh加拿大:购买婴幼儿服装和童装
2018/11/27 全球购物
我的珠宝盒:Ma boîte à bijoux
2019/08/27 全球购物
决定成败的关键——创业计划书
2014/01/24 职场文书
浪费资源的建议书
2014/03/12 职场文书
医学生就业推荐表自我鉴定
2014/03/26 职场文书
《青山处处埋忠骨》教学反思
2014/04/22 职场文书
新文化运动的口号
2014/06/21 职场文书
2014财务人员自我评价范文
2014/09/21 职场文书
单位个人查摆问题及整改措施
2014/10/28 职场文书
2016创先争优活动党员公开承诺书
2016/03/24 职场文书