封装:PDO与MySQL之间的无缝切换
以下的例子是将MySQL和PDO封装好,再无缝切换:
文件目录:

config.php文件:
<?php return array(
// 数据库配置
'DB' => array(
'default_extension'=>'mysql', //这里可以是pdo或mysql
),
// 分页配置
// 上传配置
// 图像处理配置
);
I_DB.interface.php文件:
<?php
/**
* 数据库接口
*/
interface I_DB {
public static function getInstance($config);// 获取单例对象
public function my_query($sql); //执行增删改
public function fetchAll($sql); //查询所有
public function fetchRow($sql); //查询一行
public function fetchColumn($sql); //查询一个单行单列的一个值
}
MySQLDB.class.php文件:
<?php
header('content-type:text/html;charset=utf-8');
/**
* MySQL数据库工具类
*/
//加载接口
include './I_DB.interface.php';
class MySQLDB implements I_DB{
private $host; //主机地址
private $port; //端口号
private $user; //用户名
private $pass; //密码
private $dbname; //数据库名
private $charset;//字符集
private $link; //保存连接数据库资源
private static $instance = null; //单例模式中的$MySQLDB对象 /**
*@param array $config 配置文件
*/
private function __construct ($config) { // 初始化属性的值
$this->init($config);
// 连接数据库
$this->my_connect();
// 设置字符集
$this->my_charset();
// 选择数据库
$this->my_dbname();
} /**
* 只能new一次,单例模式
*@param array $config 传递给构造方法的数组参数
*/
public static function getInstance($config) {
if (self::$instance == null) {
self::$instance = new self($config);
}
return self::$instance;
} /***
*私有化克隆魔术方法
*/
private function _clone() {} /**
*初始化
*@param array $config 传递给初始化方法的数组参数
*/
private function init($config) {
$this->host = isset($config['host'])?$config['host']:'localhost';
$this->port = isset($config['port'])?$config['port']:'3306';
$this->user = isset($config['user'])?$config['user']:'root';
$this->pass = isset($config['pass'])?$config['pass']:'';
$this->dbname = isset($config['dbname'])?$config['dbname']:'';
$this->charset = isset($config['charset'])?$config['charset']:'utf8';
} /**
*错误测试方法
*@param string $sql sql语句
*直接用途:用来增删改
*/
public function my_query($sql) {
if ($result = mysql_query($sql)) {
return $result;
}else {
echo "执行sql语句失败;<br/>";
echo "错误代码:",mysql_errno(),"<br/>";
echo "错误信息:",mysql_error(),'<br/>';
return false;
}
}
/**
*连接数据库
*/
private function my_connect() {
if ($link = mysql_connect("$this->host:$this->port",$this->user,$this->pass)) {
$this->link = $link;
}else {
echo "连接数据库失败:<br/>";
echo "错误代码:",mysql_errno(),"<br/>";
echo "错误信息:",mysql_error(),'<br/>';
return false;
}
} /**
*设置字符集
*/
private function my_charset() {
$sql = "set names $this->charset";
$this->my_query($sql);
}
/**
*选择数据库
*/
private function my_dbname() {
$sql = "use $this->dbname";
return $this->my_query($sql);
} /**
*返回多行多列的结果集,二维数组
*@param string sql语句
*@return mixed(array|false) *执行成功返回数组,失败返回false
*/
public function fetchAll($sql) {
if($result = $this->my_query($sql)) {
//返回资源结果集,遍历
$rows[] = '';
while ($row = mysql_fetch_assoc($result)) {
$rows[] = $row;
}
//结果集使用完毕,主动释放
mysql_free_result($result);
//返回二维数组
return $rows;
} else {
return false;
} } /**
* 返回一行多列的结果集,一维数组
*@param string 一条sql语句
*@return mixed(array|false) 执行成功返回数组,失败返回false
*/
public function fetchRow($sql) {
if($result = $this->my_query($sql)) {
//返回资源结果集,遍历
$row = mysql_fetch_assoc($result);
//结果集使用完毕,主动释放
mysql_free_result($result);
//返回一维数组
return $row;
} else {
return false;
}
} /**
*返回一行一列的结果集,单一值
*@param string 一条sql语句
*@return mixed(array|false) 执行成功返回数组,失败返回false
*/
public function fetchColumn($sql) {
if($result = $this->my_query($sql)) {
//返回资源结果集,提取
$row = mysql_fetch_row($result);
//结果集使用完毕,主动释放
mysql_free_result($result);
//返回单一值
return isset($row[0])?$row[0]:false;
} else {
return false;
}
} /**
*析构方法
*/
public function __destruct() {
@mysql_close($this->link);
}
/**
*__sleep 序列化对象的时候触发执行
*/
public function __sleep() {
return array('host','port','user','pass','charset','dbname') ;
} /**
*__wakeup 反序列化的时候触发执行
*初始化操作
*/ public function __wakeup() {
//初始化操作
// 连接数据库
$this->my_connect();
// 设置字符集
$this->my_charset();
// 选择数据库
$this->my_dbname();
} /**
*__set 为一个不可访问的属性赋值的时候自动触发
*@param string $name 属性名
*@param mixed $value 属性值
*/
public function __set($name,$value) {
$allow_set = array('host','port','user','pass','dbname','charset');
if(in_array($name,$allow_set)) {
//当前属性可以被赋值
$this->$name = $value;
}
} /**
*__get *获得一个不可访问的属性的值的时候自动触发
*@param string $name 属性名
*/
public function __get($name) {
$allow_get = array('host','port','user','pass','dbname','charset');
if (in_array($name,$allow_get)) {
return $this->$name;
}
} /**
*__call 访问一个不可访问的对象方法的时候触发
*@param string $name
*@param array $argument 参数列表
*/
public function __call($name, $argument) {
echo "对不起,您访问的".$name."()方法不存在!<br/>";
} /**
*__callstatic 访问一个不可访问的类方法(静态方法)的时候触发
*@param string $name
*@param array $argument 参数列表
*/
public static function __callStatic($name, $argument) {
echo "对不起,您访问的".$name."()静态方法不存在!<br/>";
} }
PDODB.class.php文件:
<?php
header('content-type:text/html;charset=utf-8');
/**
* 封装PDODB类
*/
// 加载接口
include './I_DB.interface.php';
class PDODB implements I_DB {
/**
* 定义相关属性
*/
private $host; //主机地址
private $port; //端口号
private $user; //用户名
private $pass; //密码
private $dbname; //数据库名
private $charset;//字符集
private $dsn; //数据源名称
private $pdo; //用于存放PDO的一个对象
// 静态私有属性用于保存单例对象
private static $instance; /**
* [__construct 构造方法]
* @param [array] $config [配置数组]
*/
private function __construct($config) {
// 初始化属性
$this->initParams($config);
// 初始化dsn
$this->initDSN();
// 实例化PDO对象
$this->initPDO();
// 初始化PDO对象的属性
$this->initAttribute();
} /**
* [getInstance 获取PDO单例对象的公开方法]
* @param [array] $config [description]
* @return [PDOobject] self::$instance [pdo对象]
*/
public static function getInstance($config) {
if (!self::$instance instanceof self) {
self::$instance = new self($config);
}
return self::$instance;
} /**
* [initParams 初始化属性]
* @param [array] $config [配置数组]
*/
private function initParams($config) {
$this->host = isset($config['host'])?$config['host']:'localhost';
$this->port = isset($config['port'])?$config['port']:'3306';
$this->user = isset($config['user'])?$config['user']:'root';
$this->pass = isset($config['pass'])?$config['pass']:'';
$this->dbname = isset($config['dbname'])?$config['dbname']:'';
$this->charset = isset($config['charset'])?$config['charset']:'utf8';
}
/**
* [initDSN 初始化dsn]
*/
private function initDSN() {
$this->dsn = "mysql:host=$this->host;port=$this->port;dbname=$this->dbname;charset=$this->charset";
} /**
* [initPDO 实例化PDO对象]
* @return [boolean] [false|none]
*/
private function initPDO() {
// 在实例化PDO对象的时候自动的走异常模式(也是唯一走异常模式的地方)
try{
$this->pdo = new PDO($this->dsn,$this->user,$this->pass);
}catch(PDOException $e) {
$this->my_error($e);
}
} /**
* [initAttribute 初始化PDO对象属性]
* @return [boolean] [false|none]
*/
private function initAttribute() {
// 修改错误模式为异常模式
$this->pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
} /**
* [my_error 输出异常信息]
* @param [PDOException] $e [异常对象]
* @return [boolean] [false|none]
*/
private function my_error($e) {
echo "执行sql语句失败!<br/>";
echo "错误的代码是:",$e->getCode(),"<br/>";
echo "错误的信息是:",$e->getMessage(),"<br/>";
echo "错误的脚本是:",$e->getFile(),"<br/>";
echo "错误的行号是:",$e->getLine(),'<br/>';
return false;
} /**
* [my_query 执行一条sql语句,实现增删改]
* @param [string] $sql [sql语句]
* @return [array] $result [资源结果集]
*/
public function my_query($sql) {
// 其实就是调用pdo对象中的exec方法
try{
$result = $this->pdo->exec($sql);
}catch(PDOException $e) {
$this->my_error($e);
}
return $result;
} /**
* [fetchAll 查询所有]
* @param [string] $sql [sql语句]
* @return [arry] $result [资源结果集]
*/
public function fetchAll($sql) {
// 其实就是调用PDOStatment对象里面的fetchAll方法
try{
$stmt = $this->pdo->query($sql);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 关闭游标,释放结果集
$stmt->closeCursor();
}catch(PDOException $e) {
$this->my_error($e);
}
return $result;
} /**
* [fetchRow 查询一条]
* @param [string] $sql [sql语句]
* @return [arry] $result [资源结果集]
*/
public function fetchRow($sql) {
// 其实就是调用PDOStatment对象里面的fetch方法
try{
$stmt = $this->pdo->query($sql);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
// 关闭游标,释放结果集
$stmt->closeCursor();
}catch(PDOException $e) {
$this->my_error($e);
}
return $result;
} /**
* [fetchColumn 查询单行单列]
* @param [string] $sql [sql语句]
* @return [arry] $result [资源结果集]
*/
public function fetchColumn($sql) {
// 其实就是调用PDOStatment对象里面的fetchColumn方法
try{
$stmt = $this->pdo->query($sql);
$result = $stmt->fetchColumn();
// 关闭游标,释放结果集
$stmt->closeCursor();
}catch(PDOException $e) {
$this->my_error($e);
}
return $result;
} /**
* [__clone 私有化克隆方法,保护单例模式]
*/
private function __clone() {} /**
* [__set 为一个不可访问的属性赋值的时候自动触发]
* @param [string] $name [属性名]
* @param [mixed] $value [属性值]
*/
public function __set($name,$value) {
$allow_set = array('host','port','user','pass','dbname','charset');
if(in_array($name,$allow_set)) {
//当前属性可以被赋值
$this->$name = $value;
}
} /**
* [__get *获得一个不可访问的属性的值的时候自动触发]
* @param [string] $name [属性名]
* @return [string] $name的value [该属性名的值]
*/
public function __get($name) {
$allow_get = array('host','port','user','pass','dbname','charset');
if (in_array($name,$allow_get)) {
return $this->$name;
}
} /**
* [__call 访问一个不可访问的对象方法的时候触发]
* @param [string] $name [属性名]
* @param [array] $argument [参数列表]
*/
public function __call($name, $argument) {
echo "对不起,您访问的".$name."()方法不存在!<br/>";
} /**
* [__callstatic 访问一个不可访问的类方法(静态方法)的时候触发]
* @param [string] $name [属性名]
* @param [array] $argument [参数列表]
*/
public static function __callStatic($name, $argument) {
echo "对不起,您访问的".$name."()静态方法不存在!<br/>";
}
}
最后的测试类:
<?php
header('content-type:text/html;charset=utf-8');
// 先读取配置文件
$conf = include './config.php'; $config = [
'pass'=>'123456',
'dbname'=>'bbs'
]; // 实例化数据库操作对象
switch ($conf['DB']['default_extension']) {
case 'mysql':
include './MySQLDB.class.php';
$db = MySQLDB::getInstance($config);
break;
case 'pdo':
include './PDODB.class.php';
$db = PDODB::getInstance($config);
break;
default:
break;
} $sql = "select * from user limit 4";
echo "<pre>";
var_dump($db->fetchAll($sql));
echo "</pre>";
echo "<hr>";
测试结果:

还可以在配置文件config.php中切换到pdo中操作数据库!
封装:PDO与MySQL之间的无缝切换的更多相关文章
- 面向对象的方式进行数据交换网络之间的差异--无缝切换的发展到单机游戏C/S模式
上一页本文描述描述有关数据的发展过程之间的差异支撑点,这里展示的另一个特点:无缝切换的发展,以独立C/S模式 一般C/S模式都面临一个问题: 就是开发过程中的调试难题,由于涉及到client和服务端相 ...
- log4net使用封装,无缝切换 dotnet 和 dotnetcore
log4net使用封装,无缝切换 dotnet 和 dotnetcore Intro 自己有几个自己的小项目,有许多公用的方法/扩展/工具类等等,于是封装了一些常用的工具类/扩展方法 WeihanLi ...
- MediaPlayer: 在不同控件之间实现视频的无缝切换的方法
最近使用MediaPlayer + TextureView 实现了一个视频播放器,并且实现了它的横竖屏切换的效果,唯一美中不足的是在横竖屏切换的时候画面会卡顿一下,虽然也不影响播放,但是怕测试会报Bu ...
- php-fpm 和 mysql 之间的关系
我们都知道,php是不能直接操作 mysql的,他需要通过扩展提供接口调用,php的mysql扩展也好几个,只支持面向过程的mysql,既支持面向过程也支持面向对象的mysqli,只支持面向对象的PD ...
- 手写jwt验证,实现java和node无缝切换
前言 前端时间和我朋友写了一个简易用户管理后台,功能其实很简单,涉及到的技术栈有:vue+elementUI,java+spring MVC以及node+egg,数据库用的mysql,简单方便. 一开 ...
- Android主题换肤 无缝切换
2016年7月6日 更新:主题换肤库子项目地址:ThemeSkinning,让app集成换肤更加容易.欢迎star以及使用,提供改进意见. 更新日志: v1.3.0:增加一键切换切换字体(初版)v1. ...
- MySQL原生API、MySQLi面向过程、MySQLi面向对象、PDO操作MySQL
[转载]http://www.cnblogs.com/52fhy/p/5352304.html 本文将举详细例子向大家展示PHP是如何使用MySQL原生API.MySQLi面向过程.MySQLi面向对 ...
- 面对对象之差异化的网络数据交互方式--单机游戏开发之无缝切换到C/S模式
上一篇这里描写叙述了一个关于差异数据在开发过程中的一个长处,这里来演示另外一个特点:单机开发之无缝切换到C/S模式 一般C/S模式都面临一个问题: 就是开发过程中的调试难题,由于涉及到client和服 ...
- EasyDSS视频点播服务器实现多分辨率/多码率无缝切换的办法
EasyDSS流媒体音视频直播与点播服务器软件,是一套提供一站式的转码.点播.直播.检索.回放.录像下载服务的高性能RTMP/HLS/HTTP-FLV流媒体服务,极大地简化了流媒体相关业务的开发和集成 ...
随机推荐
- Python之路,Day1 - Python基础1(转载Alex)
本节内容 Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc是个什么鬼? 数据类型初识 数据运算 表达式if ...else语 ...
- Spinrg WebFlux中Cookie的读写
WebFLux与WebMvc的差异 WebFlux读写Cookie不像WebMvc那么直接,最主要的原因是WebMvc是基于Servlet规范的,而WebFlux仅仅遵守的是HTTP协议.所以在使用的 ...
- hbase表内存的分布
- python时间处理,datetime中的strftime/strptime
python中datetime模块非常好用,提供了日期格式和字符串格式相互转化的函数strftime/strptime 1.由日期格式转化为字符串格式的函数为: datetime.datetime.s ...
- 基于PHP的一种Cache回调与自动触发技术
$s = microtime(true); for($i=0; $iaaa($array, $array, $array); $data = a::bbb($array, $array, $array ...
- leetcode 57 Insert Interval & leetcode 1046 Last Stone Weight & leetcode 1047 Remove All Adjacent Duplicates in String & leetcode 56 Merge Interval
lc57 Insert Interval 仔细分析题目,发现我们只需要处理那些与插入interval重叠的interval即可,换句话说,那些end早于插入start以及start晚于插入end的in ...
- 针对老式浏览器(主要是IE6、7、8)的css3-mediaqueries.js自适应布局
<meta name="viewport" content="width=device-width, initial-scale=1" /> vie ...
- 【html、CSS、javascript-5】css应用场景补充
一.CSS全局应用 父标签div下包含两个子标签div,当子标签dvi全部向左float,此时父标签设置的背景色是不显示的 <!DOCTYPE html> <html lang=&q ...
- angular依赖注入(1)——从父元素到子元素的数据注入
1.什么是依赖注入? 依赖注入是一种编程模式,可以让类从外部源中获得它的依赖,不必亲自创建他们. (这就达到了一个效果,我不知道我是怎么实现的,但我创建了一个实现他的接口,然后接口封装起来,1.可以分 ...
- python 升级后正确安装 pip
由于服务器的python 版本是2.6.6 , 为了使用 twisted 升级至 2.7.13 , 如果此时直接用 yum install python-pip 安装 pip, 则实际pip 会安装在 ...