封装: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中操作数据库!

时间: 2024-10-15 18:26:50

封装:PDO与MySQL之间的无缝切换的相关文章

面向对象的方式进行数据交换网络之间的差异--无缝切换的发展到单机游戏C/S模式

上一页本文描述描述有关数据的发展过程之间的差异支撑点,这里展示的另一个特点:无缝切换的发展,以独立C/S模式 一般C/S模式都面临一个问题: 就是开发过程中的调试难题,由于涉及到client和服务端相关方法,假设由某个人来编写那么也是一个简单的事情. 假设由2个人编写,会带来一些平台上的差别以及编码的差别. 简单的说,假设我们在开发时全然的避开C/S,然后经由某个机制,能够直接让模块跑到server上,那么这将让你的开发速度上升好几个倍率. 没有协议,没有交互,没有网络,那么从头写到尾,也是一件

log4net使用封装,无缝切换 dotnet 和 dotnetcore

原文:log4net使用封装,无缝切换 dotnet 和 dotnetcore log4net使用封装,无缝切换 dotnet 和 dotnetcore Intro 自己有几个自己的小项目,有许多公用的方法/扩展/工具类等等,于是封装了一些常用的工具类/扩展方法 WeihanLi.Common,日志使用了自己比较常用的 log4net,开始默认使用的log4net进行处理日志,在1.0.12版本之前直接依赖 log4net,后来觉得这样做不太好,一是多了 log4net 这一依赖而且有点一个公共

Zabbix高可用,实现zabbix的无缝切换,无故障时间

作者:骚年有梦 联系方式:[email protected] zabbix高可用设计目标: 1.keepalived服务优先级选择切换机制:对于zabbix服务器来说,只要zabbix存活和mysql存活,就能够正常记录数据,不会丢失数据,php和nginx只是web页面的访问而已,所以我在这里定义mysql和zabbix为主要服务,php和nginx为次要服务,为了实现主要服务存在,次要服务挂了:次要服务器存在,主要服务器挂了,keepalived会优先选择主要服务存在的一方作为Master,

20150113--PDO增删改查+封装PDO类

回顾 方法重写:是因为对象的访问会先去子类的类空间找,从而形成了对父类的覆盖. 继承链:类只能单继承,但是可以通过继承链来实现多继承 特殊类:final类和抽象类 接口:interface PHP重载:当访问一个权限不够或者不存在的属性或者方法的时候,会自动触发的魔术方法. 属性重载和方法重载 对象的保存和还原:serialize和unserialize(对应的类已经在内存:如果有资源属性必须进行重新加载资源),魔术方法(__sleep和__wakeup) 对象遍历:默认只能遍历public属性

【DATAGUARD】物理dg配置客户端无缝切换 (八.1)--Data Guard Broker 的配置

[DATAGUARD]物理dg配置客户端无缝切换 (八.1)--Data Guard Broker 的配置 一.1  BLOG文档结构图       一.2  前言部分   一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① Data Guard Broker 的配置 ② Fast-Start Failover 的配置 ③ Oracle DataGuard 之客户端TAF 配置 ④ 使用DGMGRL 来管理数据库 ⑤

【DATAGUARD】物理dg配置客户端无缝切换--Data Guard Broker 的配置(1)

[DATAGUARD]物理dg配置客户端无缝切换 (八.1)--Data Guard Broker 的配置 一.2.2  实验环境介绍 项目 主库 dg库 db 类型 单实例 单实例 db version 11.2.0.3 11.2.0.3 db 存储 FS type FS type ORACLE_SID oradg11g oradgphy db_name oradg11g oradg11g 主机IP地址: 192.168.59.130 192.168.59.130 OS版本及kernel版本

面对对象之差异化的网络数据交互方式--单机游戏开发之无缝切换到C/S模式

上一篇这里描写叙述了一个关于差异数据在开发过程中的一个长处,这里来演示另外一个特点:单机开发之无缝切换到C/S模式 一般C/S模式都面临一个问题: 就是开发过程中的调试难题,由于涉及到client和服务端相关方法,假设由某个人来编写那么也是一个简单的事情. 假设由2个人编写,会带来一些平台上的差别以及编码的差别. 简单的说,假设我们在开发时全然的避开C/S,然后经由某个机制,能够直接让模块跑到server上,那么这将让你的开发速度上升好几个倍率. 没有协议,没有交互,没有网络,那么从头写到尾,也

Android主题换肤 无缝切换

2016年7月6日 更新:主题换肤库子项目地址:ThemeSkinning,让app集成换肤更加容易.欢迎star以及使用,提供改进意见. 更新日志: v1.3.0:增加一键切换切换字体(初版)v1.2.1:完善之前版本View的创建v1.2.0:增加对换肤属性自定义扩展v1.1.0:可以直接加载网络上的皮肤文件 今天再给大家带来一篇干货. Android的主题换肤 ,可插件化提供皮肤包,无需Activity的重启直接实现无缝切换,可高仿网易云音乐的主题换肤. 这个链接是本次的Demo打包出来的

【DATAGUARD】物理dg配置客户端无缝切换--Fast-Start Failover的配置

[DATAGUARD]物理dg配置客户端无缝切换--Fast-Start Failover的配置 一.2.2  实验环境介绍 项目 主库 dg库 db 类型 单实例 单实例 db version 11.2.0.3 11.2.0.3 db 存储 FS type FS type ORACLE_SID oradg11g oradgphy db_name oradg11g oradg11g 主机IP地址: 192.168.59.130 192.168.59.130 OS版本及kernel版本 RHEL6