programing

Codeigniter의 get_instance () : 왜 변수에 할당합니까?

nasanasas 2020. 12. 13. 09:42
반응형

Codeigniter의 get_instance () : 왜 변수에 할당합니까?


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

라이브러리 생성을위한 사용자 가이드 에서 사용하는 것이 권장되는 방법은 다음과 같습니다 .

라이브러리 내에서 CodeIgniter 리소스 활용

라이브러리 내에서 CodeIgniter의 기본 리소스에 액세스하려면 get_instance()함수를 사용하십시오 . 이 함수는 CodeIgniter 슈퍼 객체를 반환합니다.

일반적으로 컨트롤러 함수 내에서 다음 $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-> load-> helper ( 'url'); $ CI-> load-> library ( '세션'); $ CI-> config-> item ( 'base_url'); 기타

참고 : 위 get_instance()함수가 참조로 전달되고 있음을 알 수 있습니다 .

$ CI = & get_instance ();

이건 매우 중요합니다. 참조로 할당하면 복사본을 만드는 대신 원본 CodeIgniter 개체를 사용할 수 있습니다.

관련 게시물 : 설명 $ CI = & get_instance (); / Codeigniter : 인스턴스 가져 오기

그래서 여기 내 실제 질문이 있습니다.

사용자 가이드 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()직접 호출하는 대신이 메서드를 사용하는 이유는 무엇 입니까? 그것은 보인다 는 참조 경우에도, 좋은 생각되지 않을 것 클래스 변수에 전체 컨트롤러 객체를 할당처럼. 상관 없을지도 몰라요.

I want to write a wrapper function for get_instance() so it's easier to type, and I don't have to constantly assign it to a variable.

function CI()
{
    return get_instance();
}

Or:

function CI()
{
    $CI =& get_instance();
    return $CI;
}

Then I could use CI()->class->method() from anywhere without the hassle of assigning it to a variable, it's very easy to write and understand what it does, and can result in shorter, more elegant code.

  • Is there any reason not to take this approach?
  • Is there any difference between the two CI() functions above?
  • Why is it recommended to assign get_instance() to a variable rather than calling it directly?
  • What does the & in function &get_instance(){} mean where it is defined? I know a bit about what references are for and I use them when appropriate, but I've never seen a function defined this way. If I do write a wrapper function, should I use this as well?

Please note that this is not so much a style question, but a technical one. I want to know if there are any issues, performance or otherwise, with using the method I'm suggesting.

EDIT: So far we have:

  • Method chaining is not available in php4, so assigning to a variable is a workaround (although this is fairly irrelevant as Codeigniter has dropped php4 support)
  • The minor overhead of calling a function more than once to return the object, rather than calling it once and assigning to a variable.

Anything else, or are these the only potential issues?


As far as I know, it's a matter of convenience more than anything. Chances are that you will be using the CI super object a lot in your libraries so why not assign it to a variable to make it a little easier to work with?

There are a few other things to consider...

  1. If you put this method in a helper, that method becomes a dependency for any class you are using it in. This might not be a big deal for you, but if you want to share libraries with anyone else they may not be happy about the dependency, especially since there is already a standard way of handling this in the CI community.
  2. There is a slight impact on performance because you are calling get_instance() every time you use the helper rather than storing its result in a variable.
  3. Since this is a helper method that is supposed to save you time, for anyone who is working mostly in the core MVC files of CI, setting up a helper like this would take longer than just setting it to a variable in the few places you need it.

Why is it recommended to assign get_instance() to a variable rather than calling it directly?

Most probably, it is recommended to maintain backward compatibility with php4, where objects were not passed by reference by default, but were cloned.

Is there any reason not to take this approach?

Only if you want your application to run on outdated php installations


It is necessary to assign by reference because the value of CI_Controller::$instance is subject to change if another instance of the class is created. The constructor re-assigns self::$instance each time it runs.

In general, this feels like a bad design pattern and is missing the property of a singleton that limits the class to only one instance, http://en.wikipedia.org/wiki/Singleton_pattern.

It seems possible to type, CI_Controller::get_instance()->$className->$method(); which does seem like more typing that your requested CI()->$className->$method.

Ultimately, it would make sense to require that only one instance of $instance can be created and then the need for assigning by reference would be eliminated.


Method chaining is not supported in PHP4 and CI dropped support for PHP4 very recently (from version 2.0.0). Also it's easy to write $CI than writing get_instance() every time.


I prefer uses this way, it's simple

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

It could be a combination of several things, including the already mentioned:

  • Backwards compatibility
  • Convenience
  • Style Guide

Preferably, I like the idea of this 'recommendation' as being a part of a style guide. Maybe not the official style guide of CI, but still.

Imagine that all third-party scripts for CI implements this recommendation, any developer would be able to quickly determine how these scripts are designed - although this just being a very small part of the script.

Another thing that IMO is important is the mechanics of method chaining - and doing CI()->class->method() wouldn't seem intuitive for me, knowing how the rest of CI works.


Getting the result of get_instance() by reference just makes no sense since PHP5. Sadly this bad habit seems to be deep-rooted, so let's just deal with it.

For those interested, here's an über fast instance getter:

function CI()
{
    static $CI;
    isset($CI) || $CI = CI_Controller::get_instance();

    return $CI;
}

Note that the static variable wouldn't work if it were assigned by reference.

Also, you are forced not to get by reference the result of this CI(). Extra sugar :-)

Ah, and obviously you still have the (slight) cost of the function call. You still may want to use a variable instead of calling the function dozens of times.

참고URL : https://stackoverflow.com/questions/7195544/get-instance-in-codeigniter-why-assign-it-to-a-variable

반응형