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 一个比较完善的简单文件上传
Mar 25 PHP
PHP Socket 编程
Apr 09 PHP
PHP setcookie设置Cookie用法(及设置无效的问题)
Jul 13 PHP
PHP超级全局变量数组小结
Oct 04 PHP
PHP面向对象——访问修饰符介绍
Nov 08 PHP
yii框架通过控制台命令创建定时任务示例
Apr 30 PHP
Yii结合CKEditor实现图片上传功能
Jun 13 PHP
PHP中模拟处理HTTP PUT请求的例子
Jul 22 PHP
PHP封装的字符串加密解密函数
Dec 18 PHP
thinkPHP中多维数组的遍历方法
Jan 09 PHP
PHP处理CSV表格文件的常用操作方法总结
Jul 01 PHP
laravel 解决Eloquent ORM的save方法无法插入数据的问题
Oct 21 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
东芝TOSHIBA RP-F11电路分析
2021/03/02 无线电
手把手教你使用DedeCms V3的在线采集图文教程
2007/04/03 PHP
Apache服务器无法使用的解决方法
2013/05/08 PHP
PHP实现链式操作的核心思想
2015/06/23 PHP
php 使用mpdf实现指定字段配置字体样式的方法
2019/07/29 PHP
分享20多个很棒的jQuery 文件上传插件或教程
2011/09/04 Javascript
js正文内容高亮效果的实现方法
2013/06/30 Javascript
单击和双击事件的冲突处理示例代码
2014/04/03 Javascript
当某个文本框成为焦点时即清除文本框内容
2014/04/28 Javascript
jQuery原生的动画效果
2015/07/10 Javascript
JavaScript学习笔记之DOM基础 2.4
2015/08/14 Javascript
JavaScript中数组去除重复的三种方法
2016/04/22 Javascript
基于js实现二级下拉联动
2016/12/17 Javascript
Web制作验证码功能实例代码
2017/06/19 Javascript
JS实现给json数组动态赋值的方法示例
2020/03/19 Javascript
在Vue.js中使用Mixins的方法
2017/09/12 Javascript
Servlet3.0与纯javascript通过Ajax交互的实例详解
2018/03/18 Javascript
vue 解决addRoutes动态添加路由后刷新失效问题
2018/07/02 Javascript
微信小程序与后台PHP交互的方法实例分析
2018/12/10 Javascript
vue input输入框关键字筛选检索列表数据展示
2020/10/26 Javascript
Python yield使用方法示例
2013/12/04 Python
python抓取豆瓣图片并自动保存示例学习
2014/01/10 Python
python类中super()和__init__()的区别
2016/10/18 Python
Python利用flask sqlalchemy实现分页效果
2020/08/02 Python
python 统计一个列表当中的每一个元素出现了多少次的方法
2018/11/14 Python
python3中rank函数的用法
2019/11/27 Python
详解Python中字符串前“b”,“r”,“u”,“f”的作用
2019/12/18 Python
Python列表嵌套常见坑点及解决方案
2020/09/30 Python
Python实现对word文档添加密码去除密码的示例代码
2020/12/29 Python
Html5适配iphoneX刘海屏的简单实现
2019/04/09 HTML / CSS
网上蛋糕店创业计划书
2014/01/24 职场文书
行政部工作岗位职责范本
2014/03/05 职场文书
大学生考试作弊被抓检讨书
2014/12/27 职场文书
2016年清明节网上祭英烈活动总结
2016/04/01 职场文书
详解如何使用Node.js实现热重载页面
2021/05/06 Javascript
详解Python flask的前后端交互
2022/03/31 Python