CodeIgnitor 3.0.x 之 db 类实现机制

  • 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_DBCI_DB 类使用了一种奇怪的方式实现的,这个类是在一个叫做DB的函数内声明的,根据 $query_builder=true 的配置来决定声明CI_DB的父类是CI_DB_driver还是CI_DB_query_builder,两者的区别就是后者继承自前者并在前者的基础上实现了常用语句的链式调用方法。按照声明处注释所说,CI_DB类可以理解为 CI_DB_driverCI_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) {}
}

上面的描述总结为下图:

CodeIgnitor 3.0.x 之 db 类实现机制

  • 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.cnblogs.com/feiffy/p/codeignitor3-db-class.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:CodeIgnitor 3.0.x 之 db 类实现机制 - Python技术站

(0)
上一篇 2023年4月17日
下一篇 2023年4月17日

相关文章

  • php中的登陆login实例代码

    我可以为您提供有关“php中的登录login实例代码”的完整攻略。 首先,一个基本的登录系统主要包括以下步骤: 用户输入用户名和密码 PHP代码将用户名和密码与数据库中存储的信息进行比较 如果用户名和密码匹配,则将用户重定向到应用程序的主页,否则将用户转发回登录页面并显示错误消息。 以下是一个基本的PHP登录脚本示例,其中包含上述步骤的实现: <?ph…

    PHP 2023年5月23日
    00
  • 关于PHP5和PHP7中数组实现方式的比较总结

    “关于PHP5和PHP7中数组实现方式的比较总结”,我将给出完整的攻略。 概述 PHP是一种动态脚本语言,其中数组是一个重要的数据类型。从PHP5到PHP7,PHP采取了不同的数组实现方式,其中PHP5使用了“哈希表和链表”,而PHP7使用了“哈希表和单独的数组”。 PHP5中的数组 在PHP5中,数组实现方式基于“哈希表+链表”的思想。具体来说,哈希表存储…

    PHP 2023年5月26日
    00
  • 配置php.ini实现PHP文件上传功能

    配置php.ini实现PHP文件上传功能需要注意以下步骤: 步骤一:修改php.ini文件 打开php.ini文件,找到 file_uploads 参数,确保该参数的值为 On file_uploads = On 找到 upload_max_filesize 参数,设置上传的文件最大值,例如设置为 5MB: upload_max_filesize = 5M …

    PHP 2023年5月26日
    00
  • 解析PHP无限级分类方法及代码

    解析PHP无限级分类方法及代码 在网站开发中,分类列表是常见的需要处理的数据类型,其中涉及到无限级分类问题。在PHP语言中,常见的有两种方式实现无限级分类,分别为递归和非递归方法。 递归实现无限级分类 递归实现是常见的无限级分类方法,主要思路是从顶级分类开始,逐级遍历下一级分类,直到最底层的子分类全部遍历完。 下面是一个递归实现无限级分类的PHP代码示例: …

    PHP 2023年5月26日
    00
  • PHP正在进行时-变量详解及字符串动态插入变量

    PHP正在进行时-变量详解及字符串动态插入变量 1. 变量 在PHP中,变量是存储数据的容器,它们可以保存各种类型的数据,如字符串,数字和数组等。变量在使用前需要进行声明、初始化,它们的命名需要遵循一定的规则,如不能以数字开头等。 语法 $variable_name = value; 其中,$variable_name代表变量的名字,value是变量的值,值…

    PHP 2023年5月26日
    00
  • PHP采集相关教程之一 CURL函数库

    下面我将为你详细讲解“PHP采集相关教程之一 CURL函数库”的完整攻略。 什么是CURL函数库? CURL是一个开源的用于传输数据的库,支持FTP、HTTP、HTTPS、Gopher、Telnet等许多协议,常用于爬虫、接口请求等网络数据传输场景。 CURL在PHP中是通过CURL函数库来实现的,使用CURL可以方便地进行HTTP请求与响应的处理。 CUR…

    PHP 2023年5月27日
    00
  • PHP编程求最大公约数与最小公倍数的方法示例

    PHP编程求最大公约数与最小公倍数的方法示例 最大公约数 方法一:辗转相除法 辗转相除法,也叫欧几里得算法,是一种快速求两个正整数最大公约数的方法。其基本思想是用较大数除以较小数,再用出现的余数去除除数,不断重复这个过程,直到余数为零为止,此时的除数即为两个数的最大公约数。 示例代码: function gcd($a, $b) { if ($b == 0) …

    PHP 2023年5月26日
    00
  • php购物车实现代码

    下面我将为您详细讲解“PHP购物车实现代码”的完整攻略。 购物车实现的基本流程 创建购物车对象 根据用户的行为处理购物车状态,并将相关状态保存在购物车对象中 在用户需要查看购物车页面时,从购物车对象中读取购物车状态,并使用模板引擎渲染购物车页面 创建购物车对象 概念:购物车对象中包含了商品列表,商品数目,购物车总价等信息。 在PHP中,我们可以使用数组或者对…

    PHP 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部