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 3行代码的分页算法(求起始页和结束页)
Oct 21 PHP
destoon供应信息title调用出公司名称的方法
Aug 22 PHP
Laravel执行migrate命令提示:No such file or directory的解决方法
Mar 16 PHP
PHP动态生成指定大小随机图片的方法
Mar 25 PHP
php gd等比例缩放压缩图片函数
Jun 12 PHP
PHP防止图片盗用(盗链)的方法小结
Nov 11 PHP
PHP验证码类ValidateCode解析
Jan 07 PHP
PHP多维数组排序array详解
Nov 21 PHP
PHP面向对象之里氏替换原则简单示例
Apr 08 PHP
thinkPHP框架实现的无限回复评论功能示例
Jun 09 PHP
PHP微商城开源代码实例
Mar 27 PHP
php实现根据身份证获取精准年龄
Feb 26 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
提问的智慧(2)
2006/10/09 PHP
五款PHP代码重构工具推荐
2014/10/14 PHP
PHP实现QQ登录的开原理和实现过程
2018/02/04 PHP
JavaScript 基础知识 被自己遗忘的
2009/10/15 Javascript
JavaScript 内置对象属性及方法集合
2010/07/04 Javascript
javascript 系统文件夹文件操作及参数介绍
2013/01/08 Javascript
extjs 3.31 TreeGrid实现静态页面加载json到TreeGrid里面
2013/04/02 Javascript
JQuery 常用方法和事件详细介绍
2013/04/18 Javascript
javascript实现浏览器窗口传递参数的方法
2014/09/03 Javascript
3种js实现string的substring方法
2015/11/09 Javascript
JS扩展类,克隆对象与混合类实例分析
2016/11/26 Javascript
原生JS和jQuery操作DOM对比总结
2017/01/19 Javascript
微信小程序云开发如何使用npm安装依赖
2019/05/18 Javascript
js回调函数原理与用法案例分析
2020/03/04 Javascript
js在HTML的三种引用方式详解
2020/08/29 Javascript
通过实例解析jQ Ajax操作相关原理
2020/09/23 Javascript
[01:12:35]Spirit vs Navi Supermajor小组赛 A组败者组第一轮 BO3 第二场 6.2
2018/06/03 DOTA
Python用UUID库生成唯一ID的方法示例
2016/12/15 Python
python利用socketserver实现并发套接字功能
2018/01/26 Python
Pandas 重塑(stack)和轴向旋转(pivot)的实现
2019/07/22 Python
Python实现字符串中某个字母的替代功能
2019/10/21 Python
python中自带的三个装饰器的实现
2019/11/08 Python
使用python快速实现不同机器间文件夹共享方式
2019/12/22 Python
python实现图像拼接功能
2020/03/23 Python
jupyter notebook插入本地图片的实现
2020/04/13 Python
Python Pandas 对列/行进行选择,增加,删除操作
2020/05/17 Python
python中Django文件上传方法详解
2020/08/05 Python
python中scipy.stats产生随机数实例讲解
2021/02/19 Python
利用css3实现的简单的鼠标悬停按钮
2014/11/04 HTML / CSS
营销与策划专业毕业生求职信
2013/11/01 职场文书
高中军训感想300字
2014/03/04 职场文书
标准大学生职业生涯规划书写作指南
2014/09/18 职场文书
党支部党的群众路线对照检查材料
2014/09/24 职场文书
2016关于预防职务犯罪的心得体会
2016/01/21 职场文书
2016年党员创先争优承诺书
2016/03/25 职场文书
git stash(储藏)的用法总结
2022/06/25 Servers