• CI框架在模型中切换读写库和读写库


       如果你想在控制器中切换在application/config/database.php中配置好的数据库group,那么你可以参考这篇博客:CI框架在控制器中切换读写库和读写库

       如果你是希望在模型中切换group,那么就不要像在控制器中那样做,比如这样:

    <?php 
    	class Hello_model extends CI_Model{
    		public function getInfo(){
    			$this->db = null;
    			$this->load->database("read");
    			$res = $this->db->query("select * from t1");
    			print_r($res->result_array());
    		}
    	}
     ?>

      一旦调用Hello_model中的getInfo方法的话,程序就会出错,比如报如下信息的错误:

    Message: Call to a member function query() on null

      这个信息无非就是说$this->db是null,切换group失败了。

      咱们来看一下源码是什么样的:位置在system/core/loader.php中,定位到database,如下:

    <?php 
    class CI_Loader {
      /**
       * @param mixed $params   数据库配置选项
       * @param bool  $return   是否返回database对象
       * @param bool  $query_builder  是否开启query builder
       */
      public function database($params = '', $return = FALSE, $query_builder = NULL)
      {
        // 获得CodeIgniter 对象
        $CI =& get_instance();
        // 检测是否需要加载database对象
        if ($return===FALSE && $query_builder===NULL && isset($CI->db) && is_object($CI->db) && ! empty($CI->db->conn_id)){
          return FALSE;
        }
        require_once(BASEPATH.'database/DB.php');
        if ($return === TRUE){
          return DB($params, $query_builder);
        }
        //初始化$CI->db,也就是$this->db,防止发生引用错误  
        $CI->db = '';
        // 加载DB类
        $CI->db =& DB($params, $query_builder);
        return $this;
      }
    }
    

      观察执行过程:

      1. Hello_model中的因为$this->db=null,那么执行$this->load->database("read")时,进行到上面的第13行,$CI指向了CodeIgniter对象,
      2. 但是进行if判断时,前面几个都为true,但是isset($CI->db)为false,因为前面已经设为null了,
      3. 所以继续下面的require_once,再进行判断,$return为fase,于是跳过,执行$CI->db = '';
      4. 然后又尝试进行创建db,返回一个引用,注意这里是一个对象实例的引用;而如果上一步的$return为true时,则返回一个db的对象示例。
      5. 最后返回CI_loader本身。也就是说,不管传不传参数$return,都会返回值。

      这个时候,please在Hello_model中尝试打印一下load_database()的返回值

    <?php 
    	class Hello_model extends CI_Model{
    		public function getInfo(){
    			echo '不传$return,默认为false';
    			$this->db = null;
    			print_r($this->load->database("read"));//输出为空
    
    			echo '传$return=true';
    			$this->db = null;
    			print_r($this->load->database("read",true)); //输出CI_DB_mysqli_driver Object
    		}
    	}

      上面代码有两次打印,但是只有第二次打印了一个CI_DB_mysqli_driver Object,至于第一次打印为什么是空,我也没搞明白,也没时间去看了。

      但是查看打印出来的CI_DB_mysqli_driver Object,就会发现,切换到read  group 成功了,也就是说,可以用一个值来接收$this->load->database("read",true)的返回值,

      然后,没错,可以使用$this->db来接收,然后其他的和以前没两样。如下:

    <?php 
    	class Hello_model extends CI_Model{
    
    		public function getInfo(){
    			$this->db = null;
    			$this->db = $this->load->database("read",true); //输出CI_DB_mysqli_driver Object
    			//使用read group中 exam数据库的tt表
    			$res = $this->db->query("select * from tt");
    			print_r($res->result_array());
    		}
    
    		public function otherInfo(){
    			//使用write group中 test数据库的t1表
    			$res = $this->db->query("select * from t1");
    			print_r($res->result_array());
    		}
    	}
    

      

  • 相关阅读:
    2014 年美国程序员薪资调查
    新加坡移民生活:想出都出不来了!
    mysql命令行参数
    甲骨文创始人埃里森的10大混蛋行为:曾翻微软垃圾堆
    为什么我要称自己为Javascript程序员
    原生JavaScript练习——弹出层
    Leetcode 344 Reverse String 字符串处理
    安装 Autoconf 2.69版
    Leetcode 28 Implement strStr()
    Leetcode 67 Add Binary 大数加法+字符串处理
  • 原文地址:https://www.cnblogs.com/-beyond/p/8678069.html
Copyright © 2020-2023  润新知