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使用flock阻塞写入文件和非阻塞写入文件的实例讲解

    PHP使用flock阻塞写入文件和非阻塞写入文件的实例讲解 什么是flock flock 是 PHP 内置的一个函数,用于提供文件锁机制,通过锁文件实现对文件的同步和互斥操作。flock函数可以提供导向锁和共享锁,以支持多进程之间对同一文件进行不同类型的操作。 flock的使用 flock的基本用法为: bool flock ( resource $hand…

    PHP 2023年5月27日
    00
  • 10个实用的PHP代码片段

    这里是关于“10个实用的PHP代码片段”的详细攻略。 概述 作为一个PHP开发人员,经常需要处理一些常见的任务,如字符串操作、数组操作等。本攻略将介绍10个实用的PHP代码片段,可以帮助你更容易地完成日常的开发任务。 1. 检查字符串是否包含指定子串 如果需要检查一个字符串是否包含指定的子串,可以使用strpos()函数。这个函数会返回子串在字符串中首次出现…

    PHP 2023年5月24日
    00
  • php实现签到功能的方法实例分析

    下面我来为您详细讲解“php实现签到功能的方法实例分析”的完整攻略。 一、准备工作 在开始实现签到功能之前,我们需要进行一些准备工作,如:1. 安装好PHP开发环境。2. 确定数据库类型,如Mysql等,并连接好数据库。3. 创建好签到表,记录用户签到信息。 二、实现签到功能 创建签到页面,包括对应的HTML表单。 编写PHP代码实现签到功能: 判断用户是否…

    PHP 2023年5月27日
    00
  • 中国式家长各职业达成前置条件是什么 全职业达成必备技能一览

    “中国式家长各职业达成前置条件是什么 全职业达成必备技能一览” 前置条件 无论是哪一种职业,想要成为一个中国式的“好家长”,需要具备以下前置条件: 较高的教育背景:在中国式家长的定义中,教育背景是非常重要的一项,因为他们通常认为高学历可以带来更好的契机和未来。因此,如果想要成为一个中国式家长,一个良好的教育背景是必备的。 丰富的社会经验:一个成功的中国式家长…

    PHP 2023年5月26日
    00
  • php简单实现多语言切换的方法

    那我就来详细讲解一下php简单实现多语言切换的方法吧。 一、需求描述 在开发网站时,我们需要考虑到用户来自不同的国家和地区,使用不同的语言。因此,为了能够更好地服务于全球用户,我们需要通过一种方法来简单实现多语言切换。 二、实现步骤 定义语言文件:在根目录下创建一个“language”文件夹,用于存放语言文件。在该文件夹下创建一个“zh-cn.php”文件,…

    PHP 2023年5月23日
    00
  • 微信小程序授权登录及解密unionId出错的方法

    微信小程序授权登录及解密unionId出错的方法 微信小程序授权登录已成为现代互联网应用中常见的用户验证方式。在实际开发中,如果不正确地处理用户信息,就会遇到unionId解密出错的问题。本文将详细介绍微信小程序授权登录和解密unionId的方法,解决授权登录和unionId解密出错的问题。 1. 授权登录示例 1.1 准备工作 为了实现微信小程序授权登录,…

    PHP 2023年5月30日
    00
  • php 截取字符串并以零补齐str_pad() 函数

    PHP中的str_pad()函数可以截取给定字符串的一部分,并在所截取的字符串前面添加零或其他字符,以将其的长度补齐。 该函数的语法格式如下: str_pad($str, $pad_len, $pad_str = "0", $pad_type = STR_PAD_RIGHT) 其中,$str为需要被处理的字符串,$pad_len为补齐后的…

    PHP 2023年5月26日
    00
  • 3种方法轻松处理php开发中emoji表情的问题

    这里给您详细介绍一下“3种方法轻松处理php开发中emoji表情的问题”。 什么是Emoji Emoji是一种绘文字,也叫表情符号,通常用于在文本信息中表达情感、表达状态或强调关键字。随着智能手机和社交媒体的普及,Emoji表情已经成为现代人交流中不可或缺的一部分。 PHP开发中Emoji表情的问题 在PHP开发中,如果直接将包含Emoji表情的字符串存储到…

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