You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
5.6 KiB

3 years ago
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. namespace Think;
  12. /**
  13. * ThinkPHP 数据库中间层实现类
  14. */
  15. class Db {
  16. static private $instance = array(); // 数据库连接实例
  17. static private $_instance = null; // 当前数据库连接实例
  18. /**
  19. * 取得数据库类实例
  20. * @static
  21. * @access public
  22. * @param mixed $config 连接配置
  23. * @return Object 返回数据库驱动类
  24. */
  25. static public function getInstance($config=array()) {
  26. $md5 = md5(serialize($config));
  27. if(!isset(self::$instance[$md5])) {
  28. // 解析连接参数 支持数组和字符串
  29. $options = self::parseConfig($config);
  30. // 兼容mysqli
  31. if('mysqli' == $options['type']) $options['type'] = 'mysql';
  32. // 如果采用lite方式 仅支持原生SQL 包括query和execute方法
  33. $class = !empty($options['lite'])? 'Think\Db\Lite' : 'Think\\Db\\Driver\\'.ucwords(strtolower($options['type']));
  34. if(class_exists($class)){
  35. self::$instance[$md5] = new $class($options);
  36. }else{
  37. // 类没有定义
  38. E(L('_NO_DB_DRIVER_').': ' . $class);
  39. }
  40. }
  41. self::$_instance = self::$instance[$md5];
  42. return self::$_instance;
  43. }
  44. /**
  45. * 数据库连接参数解析
  46. * @static
  47. * @access private
  48. * @param mixed $config
  49. * @return array
  50. */
  51. static private function parseConfig($config){
  52. if(!empty($config)){
  53. if(is_string($config)) {
  54. return self::parseDsn($config);
  55. }
  56. $config = array_change_key_case($config);
  57. $config = array (
  58. 'type' => $config['db_type'],
  59. 'username' => $config['db_user'],
  60. 'password' => $config['db_pwd'],
  61. 'hostname' => $config['db_host'],
  62. 'hostport' => $config['db_port'],
  63. 'database' => $config['db_name'],
  64. 'dsn' => isset($config['db_dsn'])?$config['db_dsn']:null,
  65. 'params' => isset($config['db_params'])?$config['db_params']:null,
  66. 'charset' => isset($config['db_charset'])?$config['db_charset']:'utf8',
  67. 'deploy' => isset($config['db_deploy_type'])?$config['db_deploy_type']:0,
  68. 'rw_separate' => isset($config['db_rw_separate'])?$config['db_rw_separate']:false,
  69. 'master_num' => isset($config['db_master_num'])?$config['db_master_num']:1,
  70. 'slave_no' => isset($config['db_slave_no'])?$config['db_slave_no']:'',
  71. 'debug' => isset($config['db_debug'])?$config['db_debug']:APP_DEBUG,
  72. 'lite' => isset($config['db_lite'])?$config['db_lite']:false,
  73. );
  74. }else {
  75. $config = array (
  76. 'type' => C('DB_TYPE'),
  77. 'username' => C('DB_USER'),
  78. 'password' => C('DB_PWD'),
  79. 'hostname' => C('DB_HOST'),
  80. 'hostport' => C('DB_PORT'),
  81. 'database' => C('DB_NAME'),
  82. 'dsn' => C('DB_DSN'),
  83. 'params' => C('DB_PARAMS'),
  84. 'charset' => C('DB_CHARSET'),
  85. 'deploy' => C('DB_DEPLOY_TYPE'),
  86. 'rw_separate' => C('DB_RW_SEPARATE'),
  87. 'master_num' => C('DB_MASTER_NUM'),
  88. 'slave_no' => C('DB_SLAVE_NO'),
  89. 'debug' => C('DB_DEBUG',null,APP_DEBUG),
  90. 'lite' => C('DB_LITE'),
  91. );
  92. }
  93. return $config;
  94. }
  95. /**
  96. * DSN解析
  97. * 格式: mysql://username:passwd@localhost:3306/DbName?param1=val1&param2=val2#utf8
  98. * @static
  99. * @access private
  100. * @param string $dsnStr
  101. * @return array
  102. */
  103. static private function parseDsn($dsnStr) {
  104. if( empty($dsnStr) ){return false;}
  105. $info = parse_url($dsnStr);
  106. if(!$info) {
  107. return false;
  108. }
  109. $dsn = array(
  110. 'type' => $info['scheme'],
  111. 'username' => isset($info['user']) ? $info['user'] : '',
  112. 'password' => isset($info['pass']) ? $info['pass'] : '',
  113. 'hostname' => isset($info['host']) ? $info['host'] : '',
  114. 'hostport' => isset($info['port']) ? $info['port'] : '',
  115. 'database' => isset($info['path']) ? substr($info['path'],1) : '',
  116. 'charset' => isset($info['fragment'])?$info['fragment']:'utf8',
  117. );
  118. if(isset($info['query'])) {
  119. parse_str($info['query'],$dsn['params']);
  120. }else{
  121. $dsn['params'] = array();
  122. }
  123. return $dsn;
  124. }
  125. // 调用驱动类的方法
  126. static public function __callStatic($method, $params){
  127. return call_user_func_array(array(self::$_instance, $method), $params);
  128. }
  129. }