-
Codeignitor 的 db 類的說明,鍛煉一下文字表達能力
-
一般的使用場景:
class home extends Base_Controller
{
public function test()
{
$this->load->model('my/User_model');
}
}
class User_model extend CI_Model
{
public function __construct()
{
$this->db = $this->load->database('my', TRUE);
}
}
class CI_Model
{
public function __get($key)
{
return get_instance()->$key;
}
}
-
在 controller 中加載 model 類
-
在 model 中加載 db,獲得 db 物件,可以用來查詢 sql
- model 中的 load 物件是從 controller 中獲取的
- db 物件的型別是
CI_DB_mysqli_driver
,這是 load 物件根據默認配置創建的 mysql 資料庫查詢物件 - 默認組態檔在
/config/database.php
,按照框架約定配置好資料庫引數
-
database.php 內容如下:
$active_group = 'default';
$query_builder = TRUE;
$db['default'] = array(
$db['myche'] = array(
'dsn' => '',
'hostname' => $_SERVER['DB_MY_HOST'],
'username' => $_SERVER['DB_MY_USER'],
'password' => $_SERVER['DB_MY_PASS'],
'database' => $_SERVER['DB_MY_NAME'],
'dbdriver' => 'mysqli',
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => (ENVIRONMENT !== 'production'),
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'encrypt' => FALSE,
'compress' => FALSE,
'stricton' => FALSE,
'failover' => array(),
'save_queries' => (ENVIRONMENT !== 'production')
);
);
-
CI_DB_mysqli_driver
繼承自CI_DB
,CI_DB
類使用了一種奇怪的方式實作的,這個類是在一個叫做DB
的函式內宣告的,根據$query_builder=true
的配置來決定宣告CI_DB
的父類是CI_DB_driver
還是CI_DB_query_builder
,兩者的區別就是后者繼承自前者并在前者的基礎上實作了常用陳述句的鏈式呼叫方法,按照宣告處注釋所說,CI_DB
類可以理解為CI_DB_driver
和CI_DB_query_builder
的別名, -
CI_DB_mysqli_driver
的創建程序:- 在 load 物件的 database 方法中呼叫 DB 函式
- 在 DB 函式中
- 宣告
CI_DB
,根據$query_builder=true
的配置來決定CI_DB
的父類是CI_DB_driver
還是CI_DB_query_builder
, - 根據
dbdriver
配置加載資料庫驅動類檔案,并實體化CI_DB_mysqli_driver
,并回傳此物件,
- 宣告
-
DB 函式的實作
function &DB($params = '', $query_builder_override = NULL)
{
require_once(BASEPATH.'database/DB_driver.php');
if ( ! isset($query_builder) OR $query_builder === TRUE)
{
require_once(BASEPATH.'database/DB_query_builder.php');
if ( ! class_exists('CI_DB', FALSE))
{
/**
* CI_DB
*
* Acts as an alias for both CI_DB_driver and CI_DB_query_builder.
*
* @see CI_DB_query_builder
* @see CI_DB_driver
*/
class CI_DB extends CI_DB_query_builder { }
}
}
elseif ( ! class_exists('CI_DB', FALSE))
{
class CI_DB extends CI_DB_driver { }
}
// Load the DB driver
$driver_file = BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php';
require_once($driver_file);
// Instantiate the DB adapter
$driver = 'CI_DB_'.$params['dbdriver'].'_driver';
$DB = new $driver($params);
return $DB;
}
-
CI_DB_mysqli_driver
最終是繼承自CI_DB_driver
這個抽象類,CI_DB_driver
定義了資料庫驅動類需要實作的一些通用方法,具體的驅動類比如CI_DB_mysqli_driver
則實作了這些方法, -
CI_DB_driver
關鍵方法定義
abstract class CI_DB_driver {
// db 連接
function db_connect() {}
// db 長連接
function db_pconnect() {}
// 設定連接字符集編碼
function _db_set_charset() {}
// 選擇資料庫
function db_select() {}
// 開始事務
function _trans_begin() {}
// 回滾事務
function _trans_rollback() {}
// 提交事務
function _trans_commit() {}
// 執行查詢
function _execute($sql) {}
}
上面的描述總結為下圖:
CI_DB_mysqli_driver
的部分實作
class CI_DB_mysqli_driver extends CI_DB {
// 連接資料庫
public function db_connect($persistent = FALSE)
{
// Do we have a socket path?
if ($this->hostname[0] === '/')
{
$hostname = NULL;
$port = NULL;
$socket = $this->hostname;
}
else
{
// Persistent connection support was added in PHP 5.3.0
$hostname = ($persistent === TRUE && is_php('5.3'))
? 'p:'.$this->hostname : $this->hostname;
$port = empty($this->port) ? NULL : $this->port;
$socket = NULL;
}
$client_flags = ($this->compress === TRUE) ? MYSQLI_CLIENT_COMPRESS : 0;
$this->_mysqli = mysqli_init();
$this->_mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 10);
// ... 此處省略一些設定的代碼
if ($this->_mysqli->real_connect($hostname, $this->username, $this->password, $this->database, $port, $socket, $client_flags))
{
// Prior to version 5.7.3, MySQL silently downgrades to an unencrypted connection if SSL setup fails
if (
($client_flags & MYSQLI_CLIENT_SSL)
&& version_compare($this->_mysqli->client_info, '5.7.3', '<=')
&& empty($this->_mysqli->query("SHOW STATUS LIKE 'ssl_cipher'")->fetch_object()->Value)
)
{
$this->_mysqli->close();
$message = 'MySQLi was configured for an SSL connection, but got an unencrypted connection instead!';
log_message('error', $message);
return ($this->db->db_debug) ? $this->db->display_error($message, '', TRUE) : FALSE;
}
return $this->_mysqli;
}
return FALSE;
}
}
-
這里
mysqli_init
函式是 php 擴展自帶的函式,回傳的是 php 的 resource 型別的物件,即 mysqli 物件,這個物件可以用來查詢資料庫, -
再看下
CI_DB_query_builder
的部分實作,主要的功能是基于 driver 的方法,實作很多人性化的、可以鏈式呼叫的方法,
abstract class CI_DB_query_builder extends CI_DB_driver
{
public function limit($value, $offset = 0)
{
is_null($value) OR $this->qb_limit = (int) $value;
empty($offset) OR $this->qb_offset = (int) $offset;
return $this;
}
public function offset($offset)
{
empty($offset) OR $this->qb_offset = (int) $offset;
return $this;
}
public function get($table = '', $limit = NULL, $offset = NULL)
{
if ($table !== '')
{
$this->_track_aliases($table);
$this->from($table);
}
if ( ! empty($limit))
{
$this->limit($limit, $offset);
}
$result = $this->query($this->_compile_select());
$this->_reset_select();
return $result;
}
function select() {}
function distinct() {}
function join() {}
function from() {}
function where() {}
function or_where() {}
function like() {}
function group_by() {}
function having() {}
function update() {}
// ...
}
不積跬步,無以至千里;不積小流,無以成江海
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/548317.html
標籤:PHP