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操作xml代码
Jun 17 PHP
php XMLWriter类的简单示例代码(RSS输出)
Sep 30 PHP
PHP设计模式之解释器模式的深入解析
Jun 13 PHP
解析将多维数组转换为支持curl提交的一维数组格式
Jul 08 PHP
mac下安装nginx和php
Nov 04 PHP
php三元运算符知识汇总
Jul 02 PHP
PHP实现的memcache环形队列类实例
Jul 28 PHP
thinkphp jquery实现图片上传和预览效果
Jul 22 PHP
php 浮点数比较方法详解
May 05 PHP
PHP编程获取各个时间段具体时间的方法
May 26 PHP
PHP进阶学习之Geo的地图定位算法详解
Jun 19 PHP
Laravel获取所有的数据库表及结构的方法
Oct 10 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
php foreach 参数强制类型转换的问题
2010/12/10 PHP
护卫神php套件 php版本升级方法(php5.5.24)
2015/05/10 PHP
php使用GD实现颜色渐变实例
2015/06/02 PHP
php实现的一段简单概率相关代码
2016/05/30 PHP
php字符串操作常见问题小结
2016/10/11 PHP
详解ThinkPHP3.2.3验证码显示、刷新、校验
2016/12/29 PHP
侧栏跟随滚动的简单实现代码
2013/03/18 Javascript
JS实现从表格中动态删除指定行的方法
2015/03/31 Javascript
jQuery插件bgStretcher.js实现全屏背景特效
2015/06/05 Javascript
js流动式效果显示当前系统时间
2016/05/16 Javascript
jQuery 获取屏幕高度、宽度的简单实现案例
2016/05/17 Javascript
JS实现的tab切换选项卡效果示例
2017/02/28 Javascript
基于bootstrop常用类总结(推荐)
2017/09/11 Javascript
JavaScript实现二叉树定义、遍历及查找的方法详解
2017/12/20 Javascript
Python中input与raw_input 之间的比较
2017/08/20 Python
python实现Flappy Bird源码
2018/12/24 Python
JupyterNotebook 输出窗口的显示效果调整方法
2020/04/13 Python
Python使用configparser读取ini配置文件
2020/05/25 Python
python实现数字炸弹游戏程序
2020/07/17 Python
HTML5对比HTML4的主要改变和改进总结
2016/05/27 HTML / CSS
菲律宾旅游网站:Expedia菲律宾
2017/10/11 全球购物
LEGO玩具英国官方商店:LEGO Shop GB
2018/03/27 全球购物
美国爆米花工厂:The Popcorn Factory
2019/09/14 全球购物
外企C语言笔试题
2013/11/10 面试题
旅游管理本科生求职信
2013/10/14 职场文书
艺术系应届生的自我评价
2013/10/19 职场文书
《口技》教学反思
2014/02/21 职场文书
《可爱的动物》教学反思
2014/02/22 职场文书
《猫》教学反思
2014/02/26 职场文书
党代会心得体会
2014/09/04 职场文书
学用政策心得体会
2014/09/10 职场文书
医德医魂心得体会
2014/09/11 职场文书
2014年班长个人工作总结
2014/11/14 职场文书
怎样评估创业计划书是否有可行性?
2019/08/07 职场文书
springboot 启动如何排除某些bean的注入
2021/08/02 Java/Android
使用RedisTemplat实现简单的分布式锁
2021/11/20 Redis