<?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 { private static $instance = array(); // 数据库连接实例 private static $_instance = null; // 当前数据库连接实例 /** * 取得数据库类实例 * * @static * * @access public * @param mixed $config * 连接配置 * @return Object 返回数据库驱动类 */ static public function getInstance($config = array()) { $md5 = md5(serialize($config)); if (! isset(self::$instance[$md5])) { // 解析连接参数 支持数组和字符串 $options = self::parseConfig($config); // 兼容mysqli if ('mysqli' == $options['type']) { $options['type'] = 'mysql'; } // 如果采用lite方式 仅支持原生SQL 包括query和execute方法 $class = $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); $config = array( 'type' => $config['db_type'], 'username' => $config['db_user'], 'password' => $config['db_pwd'], 'hostname' => $config['db_host'], 'hostport' => $config['db_port'], 'database' => $config['db_name'], 'dsn' => isset($config['db_dsn']) ? $config['db_dsn'] : null, '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); 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); } }