在Codeigniter中,get_instance()
是一个全局可用的函数,它返回Controller超级对象,它包含所有当前加载的类(它返回Controller类实例)。我将包含当前的源代码:
get_instance()
在Codeigniter.php
// Load the base controller class
require BASEPATH.'core/Controller.php';
function &get_instance()
{
return CI_Controller::get_instance();
}
CI_Controller
Controller.php
class CI_Controller {
private static $instance;
/**
* Constructor
*/
public function __construct()
{
self::$instance =& $this;
// Assign all the class objects that were instantiated by the
// bootstrap file (CodeIgniter.php) to local class variables
// so that CI can run as one big super object.
foreach (is_loaded() as $var => $class)
{
$this->$var =& load_class($class);
}
$this->load =& load_class('Loader', 'core');
$this->load->set_base_classes()->ci_autoloader();
log_message('debug', "Controller Class Initialized");
}
public static function &get_instance()
{
return self::$instance;
}
}
以下是建议在user guide for creating libraries中使用的方式:
利用库中的CodeIgniter资源
要访问库中的CodeIgniter本机资源,请使用
get_instance()
功能。此函数返回CodeIgniter super 对象通常在您的控制器功能中,您将调用任何一个 使用
然而,$this
构造的可用CodeIgniter函数:$this->load->helper('url'); $this->load->library('session'); $this->config->item('base_url');
等。
$this
只能在您的控制器中直接使用 模型或您的观点。如果您想使用CodeIgniter的类 您可以在自己的自定义类中执行以下操作:首先,将CodeIgniter对象分配给变量:
$ CI =& get_instance();
将对象分配给变量后,您将使用它 变量而不是
$this
: $ CI =& get_instance(); $ CI->负载>辅助( 'URL'); $ CI->负载>库( '会话'); $ CI-> config->项( 'BASE_URL');等注意:您会注意到上面的
get_instance()
功能正在发生 通过引用传递:$ CI =& get_instance();
这非常重要。按引用分配可让您使用 原始的CodeIgniter对象,而不是创建它的副本。
相关帖子:explain $CI =& get_instance(); / Codeigniter: Get Instance
所以,这是我的实际问题:
为什么用户指南建议为变量分配get_instance()
?我很确定我理解不通过引用分配的含义,但为什么在get_instance()->load->model()
工作正常时建议将它分配给变量?
我在CI中看到很多用户定义的或第三方类,它们分配给对象的属性:
class MY_Class {
private $CI;
function __construct()
{
$this->CI =& get_instance();
}
function my_func()
{
$this->CI->load->view('some_view');
}
function my_other_func()
{
$this->CI->load->model('some_model');
}
}
可怜的例子,但我经常看到这一点。为什么要使用这种方法而不是直接调用get_instance()
? 似乎就像将整个Controller对象分配给一个类变量一样,即使它是一个引用也不是一个好主意。也许没关系。
我想为get_instance()
编写一个包装函数,因此更容易输入,而且我不必经常将它分配给变量。
function CI()
{
return get_instance();
}
或者:
function CI()
{
$CI =& get_instance();
return $CI;
}
然后我可以从任何地方使用CI()->class->method()
而无需将其分配给变量,编写和理解它的功能非常容易,并且可以生成更短,更优雅的代码。
CI()
函数之间是否有任何区别?get_instance()
分配给变量而不是直接调用它?&
中function &get_instance(){}
表示定义的位置是什么意思?我对references的含义有所了解,并在适当时使用它们,但我从未见过以这种方式定义的函数。如果我写一个包装函数,我也应该使用它吗?请注意,这不是一个风格问题,而是技术问题。我想知道是否有任何问题,性能或其他,使用我建议的方法。
编辑:到目前为止,我们已经:
还有其他什么,或者这些是唯一潜在的问题?
答案 0 :(得分:22)
据我所知,这比方便更重要。您可能会在库中大量使用CI超级对象,那么为什么不将它分配给变量以使其更容易使用?
还有其他一些事情要考虑......
get_instance()
,而不是将结果存储在变量中。答案 1 :(得分:3)
为什么建议将get_instance()分配给变量 比直接打电话?
最有可能的是,建议保持与php4的向后兼容性,其中默认情况下对象不是通过引用传递的,而是克隆的。
有没有理由不接受这种方法?
仅当您希望应用程序在过时的php安装上运行时
答案 2 :(得分:3)
最近PHP4
CI
PHP4
对2.0.0
的支持不支持方法链接(来自版本$CI
)。另外,每次写get_instance()
都比写{{1}}容易。
答案 3 :(得分:3)
必须通过引用进行分配,因为如果创建了另一个类实例,CI_Controller::$instance
的值可能会发生变化。构造函数每次运行时都会重新分配self::$instance
。
一般来说,这感觉就像一个糟糕的设计模式,并且缺少单例的属性,只能将类限制为一个实例http://en.wikipedia.org/wiki/Singleton_pattern。
似乎可以输入CI_Controller::get_instance()->$className->$method();
,这似乎更符合您要求的CI()->$className->$method
。
最终,要求只能创建$instance
的一个实例才有意义,然后才能消除通过引用分配的需要。
答案 4 :(得分:2)
我更喜欢用这种方式,它很简单
class Test
{
//magic method __get, whit this can use $this->load
//instead create a variable ci, then do $this->ci->load, cool :)
public function __get($var)
{
return get_instance()->$var;
}
public function showUrl()
{
$this->load->helper("url");
echo base_url();
}
}
答案 5 :(得分:1)
它可能是几件事的组合,包括已经提到的:
最好,我喜欢将这个“推荐”作为风格指南的一部分。也许不是CI的官方风格指南,但仍然。
想象一下,CI的所有第三方脚本都实现了这一建议,任何开发人员都能够快速确定这些脚本的设计方式 - 尽管这只是脚本的一小部分。
IMO最重要的另一件事是方法链的机制 - 而CI()->class->method()
对我来说似乎不太直观,知道CI的其余部分是如何工作的。
答案 6 :(得分:0)
从PHP5开始,通过引用获得get_instance()
的结果毫无意义。可悲的是,这种坏习惯似乎根深蒂固,所以让我们来处理它。
对于那些感兴趣的人,这里有一个超快速实例getter:
function CI()
{
static $CI;
isset($CI) || $CI = CI_Controller::get_instance();
return $CI;
}
请注意,如果静态变量是通过引用分配的,则静态变量不起作用。
此外,您不得通过引用获取此CI()
的结果。额外的糖: - )
啊,显然你仍然有功能调用的(轻微)成本。你仍然可能想要使用变量而不是几十次调用函数。