代码说

code is poetry

代码说    
碎碎念:秋意浓,离人心上秋意浓。一杯酒,情绪万种。  换一换

CI中自定义库类引用config对象的方法失败的问题

作者:coderzheng 发布于:2015-2-10 1:17 Tuesday 分类:php  阅读模式

在application/libraries下自定义一个类Mylib.php, 代码如下:
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class CI_Mylib {
    public $c;
   
    public function sc() {
        $str = 'sc';
        return $str;
    }
   
    public function sd() {
        $str = $this->config->item('css_path');
        var_dump($str);
        exit;
    }
}
程序试图直接在sd方法中引用config对象的item方法,但是却失败了:

将同样的代码放在controller、model和view层中的任意位置,都能正常运行:
$s = $this->config->item('css_path');
var_dump($s);
来分析一下原因:
对于controller:
因为controller的类继承了CI_Controller, 而controller的构造函数会主动调用parent::__contruct方法,来看这个方法:
self::$instance =& $this;
foreach (is_loaded() as $var => $class)
{
      $this->$var =& load_class($class);
}
循环体内其实就已经加载了config对象。
对于model:
我们看到任意一个model类都继承了CI_Model,来看CI_Model:
function __get($key)
{
      $CI =& get_instance();
      return $CI->$key;
}
__get方法会在对象调用不存在的方法时主动执行,因此config对象也会在这里被加载进来。
对于view:
由于view层的php代码实际上是"内嵌"在controller的php代码中的,即view层的php文件只是做了一次数据解析,因此可以将在view层出现的$this理解为controller层的$this,由于controller层已经解决了config调用的问题, 因此view层的引用也是会成功的。
但是对于自定义的类, 引用却是失败,因为它确实没有对config对象的装载,解决方法如下:
public function sd() {
      $obj = &get_instance();
      $this->config = $obj->config;
      $str = $this->config->item('css_path');
      var_dump($str);
      exit;
}
首先调用get_instance()方法将$obj指向全局超级对象,然后将类中当前的config挂接到超级对象的config,这样就完成了对当前类中的config对象的装载。


// 2015.2.11更新
对于controller,本文遗漏了非常重要的一点:必须先在构造函数中主动调用父类CI_Controller的构造函数,否则同样无法使用config对象的相关方法。这里必须清楚的是:类之间在进行继承时,子类是可以继承父类的构造函数的,使用parent::__construct()语句(如果父类的构造函数不需要传参)就可以调用父类的构造方法了。




==================================== 全文完 ====================================

标签: 疑难杂症 codeIgniter

你可以发表评论、引用到你的网站或博客,或通过RSS 2.0订阅这个博客的所有文章。
上一篇: 访问CI中的application或者system文件夹内的文件时返回403 Forbidden的问题  |  下一篇:模拟银行ATM机的用户登录设计