Php 在Codeigniter中获取_instance():为什么要将其分配给变量?

Php 在Codeigniter中获取_instance():为什么要将其分配给变量?,php,codeigniter,singleton,reference,Php,Codeigniter,Singleton,Reference,在Codeigniter中,get_instance()是一个全局可用的函数,它返回包含当前加载的所有类的控制器超级对象(它返回控制器类实例)。我将包括当前的源代码: Codeigniter.php // Load the base controller class require BASEPATH.'core/Controller.php'; function &get_instance() { return CI_Controller::get_instance(); }

在Codeigniter中,
get_instance()
是一个全局可用的函数,它返回包含当前加载的所有类的控制器超级对象(它返回控制器类实例)。我将包括当前的源代码:

Codeigniter.php

// Load the base controller class
require BASEPATH.'core/Controller.php';

function &get_instance()
{
    return CI_Controller::get_instance();
}
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;
    }
}
CI_Controller
Controller.php

// Load the base controller class
require BASEPATH.'core/Controller.php';

function &get_instance()
{
    return CI_Controller::get_instance();
}
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;
    }
}
以下是建议在中使用的方法:

利用库中的CodeIgniter资源 要访问库中CodeIgniter的本机资源,请使用
get\u instance()
函数。此函数返回CodeIgniter super 反对

通常,在控制器功能中,您将调用 可用的CodeIgniter功能使用
$this
结构:
$this->load->helper('url')$此->加载->库(“会话”);
$this->config->item('base_url')

$this
,但是,它只能直接在您的控制器、您的 模型,或您的视图。如果您想使用CodeIgniter的类 在您自己的自定义类中,您可以按如下方式进行操作:

首先,将CodeIgniter对象指定给一个变量:

$CI=&get_instance()

将对象指定给变量后,将使用该变量 变量而不是
$this
: $CI=&get_instance(); $CI->load->helper('url')$CI->load->library(“会话”); $CI->config->item('base_url');等等

注意:您会注意到上面的
get\u instance()
函数正在运行 通过引用:

$CI=&get_instance()

这一点非常重要。通过引用分配允许您使用 原始CodeIgniter对象,而不是创建其副本

相关员额:

所以,这是我的实际问题:

为什么用户指南建议将
get\u instance()
赋值给变量?我很确定我理解不通过引用赋值的含义,但是为什么建议在
get\u 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\u instance()
?将整个控制器对象分配给类变量似乎不是一个好主意,即使它是一个引用。也许没关系

我想为
get_instance()
编写一个包装函数,这样更容易键入,而且不必经常将它赋给变量

function CI()
{
    return get_instance();
}
或:

然后,我可以在任何地方使用
CI()->class->method()
,而无需将其分配给变量,编写和理解它的功能非常容易,并且可以生成更短、更优雅的代码

  • 有什么理由不采取这种做法吗
  • 上述两个
    CI()
    函数之间有什么区别吗
  • 为什么建议将
    get\u instance()
    分配给变量,而不是直接调用它
  • 函数&get_instance(){}
    中的
    &
    是什么意思?我知道一些函数的用途,并在适当的时候使用它们,但我从未见过这样定义的函数。如果我写了一个包装器函数,我应该也使用它吗
请注意,这不是一个风格的问题,而是一个技术问题。我想知道使用我建议的方法是否存在性能或其他问题

编辑:到目前为止,我们有:

  • 方法链接在php4中不可用,因此分配给变量是一种解决方法(尽管这与Codeigniter已放弃php4支持无关)
  • 多次调用函数以返回对象,而不是一次调用函数并将其赋值给变量,这会带来较小的开销

还有什么,或者这些是唯一的潜在问题吗?

据我所知,这是一个更方便的问题。您可能会在库中大量使用CI super对象,因此为什么不将其分配给一个变量以使其更易于使用呢

还有一些其他的事情要考虑……<
  • 如果将此方法放在助手中,则该方法将成为使用它的任何类的依赖项。这对您来说可能没什么大不了的,但是如果您想与其他人共享库,他们可能会对依赖关系不满意,特别是因为在CI社区中已经有了处理这一问题的标准方法
  • 这对性能有轻微影响,因为每次使用帮助程序时都调用
    get\u instance()
    ,而不是将其结果存储在变量中
  • 由于这是一种帮助器方法,应该可以节省您的时间,因此对于主要在CI的核心MVC文件中工作的任何人来说,设置这样的帮助器所需的时间比仅在少数需要的地方将其设置为变量所需的时间要长
  • 为什么建议将get_instance()赋值给变量而不是 而不是直接打电话

    最可能的情况是,建议保持与php4的向后兼容性,在php4中,默认情况下对象不是通过引用传递的,而是克隆的

    有什么理由不采取这种做法吗


    仅当您希望应用程序在过时的php安装上运行时,它可能是多种因素的组合,包括前面提到的:

    • 向后兼容性
    • 方便
    • 风格指南
    最好是,我喜欢将这个“建议”作为风格指南的一部分。也许不是词的官方风格指南,但仍然如此

    <
    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();
        }
    }