thinkphp核心源码注释|DB.class.php

来源:互联网 发布:nodejs数组增加元素 编辑:程序博客网 时间:2024/05/16 00:55
<?php// +----------------------------------------------------------------------// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]// +----------------------------------------------------------------------// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.// +----------------------------------------------------------------------// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )// +----------------------------------------------------------------------// | Author: liu21st <liu21st@gmail.com>// +----------------------------------------------------------------------namespace Think;/** * ThinkPHP 数据库中间层实现类 * 从类的规则上看,看来是个基础类。 * 很经典的,实现的主从,多数据库连接的。 */class Db {    static private  $instance   =  array();     //  数据库连接实例  仓库    static private  $_instance  =  null;   //  当前数据库连接实例 单独返回    /**     * 取得数据库类实例     * @static     * @access public     * @param mixed $config 连接配置     * @return Object 返回数据库驱动类     */    static public function getInstance($config=array()) {        $md5    =   md5(serialize($config)); // 跟那个 to_guid_string 有点相似啊        if(!isset(self::$instance[$md5])) {            // 解析连接参数 支持数组和字符串            $options    =   self::parseConfig($config);// 解析的抽离,漂亮!            // 兼容mysqli            if('mysqli' == $options['type']) $options['type']   =   'mysql';// 大哥,你这个是欺骗啊!            // 嗯,的确是个欺骗, 内核函数用的都是 PDO 哎,我还以为默认的配置是 myslqi 呢            // 如果采用lite方式 仅支持原生SQL 包括query和execute方法            $class  =   !empty($options['lite'])?  'Think\Db\Lite' :   'Think\\Db\\Driver\\'.ucwords(strtolower($options['type']));            if(class_exists($class)){// 类存在判读                self::$instance[$md5]   =   new $class($options);            }else{                // 类没有定义                E(L('_NO_DB_DRIVER_').': ' . $class);            }        }        self::$_instance    =   self::$instance[$md5];        return self::$_instance;    }    /**     * 数据库连接参数解析     * @static     * @access private     * @param mixed $config     * @return array     */    static private function parseConfig($config){        if(!empty($config)){ // 这里就体现了参数解析的优先级,临时配置的先解析,否则去寻找默认配置            if(is_string($config)) {                return self::parseDsn($config);            }            $config =   array_change_key_case($config);            // 默认小写 array_change_key_case() 函数将数组的所有的键都转换为大写字母或小写字母。            $config = array (                'type'          =>  $config['db_type'],// 数据库类型 常用mysqli  其实开的是pdo                'username'      =>  $config['db_user'],// 登录数据库的用户名                'password'      =>  $config['db_pwd'],// 密码                'hostname'      =>  $config['db_host'],// 主机位置                'hostport'      =>  $config['db_port'],// 端口号,默认 3306                'database'      =>  $config['db_name'],// 数据库名称                'dsn'           =>  isset($config['db_dsn'])?$config['db_dsn']:null,// 明确是否使用dsn配置方式                'params'        =>  isset($config['db_params'])?$config['db_params']:null,// 数据库解析                'charset'       =>  isset($config['db_charset'])?$config['db_charset']:'utf8',// 默认字符集设置                'deploy'        =>  isset($config['db_deploy_type'])?$config['db_deploy_type']:0,// 是否分布式支持                'rw_separate'   =>  isset($config['db_rw_separate'])?$config['db_rw_separate']:false,// 配置是否读写分类                'master_num'    =>  isset($config['db_master_num'])?$config['db_master_num']:1,// 主要数据库 数量                'slave_no'      =>  isset($config['db_slave_no'])?$config['db_slave_no']:'',// 从库数量                'debug'         =>  isset($config['db_debug'])?$config['db_debug']:APP_DEBUG,// 是否开启调试                'lite'          =>  isset($config['db_lite'])?$config['db_lite']:false,//另外的一种数据库形式,暂时没有做研究中.........            );        }else { // 寻找默认配置中 解释同上            $config = array (                'type'          =>  C('DB_TYPE'),                'username'      =>  C('DB_USER'),                'password'      =>  C('DB_PWD'),                'hostname'      =>  C('DB_HOST'),                'hostport'      =>  C('DB_PORT'),                'database'      =>  C('DB_NAME'),                'dsn'           =>  C('DB_DSN'),                'params'        =>  C('DB_PARAMS'),                'charset'       =>  C('DB_CHARSET'),                'deploy'        =>  C('DB_DEPLOY_TYPE'),                'rw_separate'   =>  C('DB_RW_SEPARATE'),                'master_num'    =>  C('DB_MASTER_NUM'),                'slave_no'      =>  C('DB_SLAVE_NO'),                'debug'         =>  C('DB_DEBUG',null,APP_DEBUG),                'lite'          =>  C('DB_LITE'),            );        }        return $config;    }    /**     * DSN解析     * 格式: mysql://username:passwd@localhost:3306/DbName?param1=val1¶m2=val2#utf8     * @static     * @access private     * @param string $dsnStr     * @return array     */    static private function parseDsn($dsnStr) {        if( empty($dsnStr) ){return false;}        $info = parse_url($dsnStr);// 通过url的格式解析器,进行解析的,牛叉,好友创意        if(!$info) {            return false;        }        $dsn = array(            'type'      =>  $info['scheme'],            'username'  =>  isset($info['user']) ? $info['user'] : '',            'password'  =>  isset($info['pass']) ? $info['pass'] : '',            'hostname'  =>  isset($info['host']) ? $info['host'] : '',            'hostport'  =>  isset($info['port']) ? $info['port'] : '',            'database'  =>  isset($info['path']) ? substr($info['path'],1) : '',            'charset'   =>  isset($info['fragment'])?$info['fragment']:'utf8',        );        if(isset($info['query'])) {            parse_str($info['query'],$dsn['params']);// 可以解析其 字符串        }else{            $dsn['params']  =   array();        }        return $dsn;     }    // 总结,挺简单的,两个系统函数就搞定了,格式的转换    // 调用驱动类的方法  这个也是个申请的函数,不错!    static public function __callStatic($method, $params){        return call_user_func_array(array(self::$_instance, $method), $params);    }}// 总结,其实,这个类,也没干什么// 第一针对于 mysql 统一传到 msyql.php 驱动中,内核驱动用的pdo// 第二:解析了配置参数,体现了传入参数的优先级// 第三:做了一个格式的转换而已// 第四:通过 魔术方法实现了动态调用。

0 0
原创粉丝点击