Объяснить $CI = & get_instance();

Просматривая исходный код codeigniter,

в своих вспомогательных функциях я вижу код $CI =& get_instance(); может ли кто-нибудь объяснить мне, как работает этот код?

Я получаю, что он возвращает ссылку на супер-объект $CI, но откуда get_instance() появляется?

Ответ 1

В основном это шаблон дизайна Singleton, который использует функцию вместо статического метода.

Чтобы посмотреть глубже, посмотрите исходный код

Таким образом, в основном это не обеспечивает синглтон, но это ярлык для публичной функции...

Изменить: Собственно, теперь я понимаю. Для совместимости с PHP4 они должны были выполнить double-global-variable-hack, чтобы заставить его правильно вернуть ссылки. В противном случае ссылки будут все испорчены. И так как PHP4 не поддерживал статические методы (ну, в любом случае, так или иначе), использование функции было лучшим способом. Таким образом, он по-прежнему существует по наследству...

Итак, если ваше приложение имеет только PHP5, нечего делать с CI_Base::get_instance();, но он идентичен...

Ответ 2

В некоторых случаях вам может понадобиться разработать классы, которые существуют отдельно от ваших контроллеров, но имеют возможность использовать все ресурсы для воссоздания кода. Это легко можно использовать с помощью функций get_instance().

Любой класс, который вы создаете в своих функциях контроллера, может обращаться к собственным ресурсам Code Igniter, просто используя функцию get_instance(). Эта функция возвращает основной объект Ignite Code.

Обычно для вызова любой из доступных функций Code Igniter требуется использовать $this  построить:

$this->load->helper('url');
$this->load->library('session');
$this->config->item('base_url');

и др.

$this, однако, работает только внутри ваших контроллеров, ваших моделей или ваших просмотров. Если вы хотите использовать классы Code Igniter из своих собственных пользовательских классов, вы можете сделать это следующим образом:

Сначала назначьте объект Code Igniter переменной:

$obj =& get_instance();

Как только вы назначили объект переменной, вы будете использовать эту переменную вместо $this:

$obj =& get_instance();
$obj->load->helper('url');
$obj->load->library('session');
$obj->config->item('base_url');

и др.

Примечание. Вы заметите, что вышеуказанная функция get_instance() передается по ссылке:

$obj =& get_instance();

Это очень важно. Присвоение по ссылке позволяет использовать исходный объект кода Igniter, а не создавать его копию.

Вы можете прочитать об этой функции из здесь

Ответ 3

get_instance() - это функция, определенная в основных файлах CodeIgniter. Вы используете его для получения ссылки singleton на суперъект CodeIgniter, когда вы находитесь в области вне супер-объекта.

Я уверен, что он определен в base.php или что-то подобное.

Ответ 4

это одноэлементная структура, чтобы понять, как codeigniter загружает библиотеки и классы

<?php

/*
====================================
start of the loader class
====================================
*/
class Loader {


  protected function _init_class($class){
    $C = Controller::get_instance();
    $name = strtolower($class);
    $C->$name = new $class();
  }

  public function _class($library){
    if(is_array($library)){
      foreach($library as $class){
        $this->library($class);
      }
      return;
    }

    if($library == ''){
      return false;
    }

    $this->_init_class($library);
  }

  public function view ($param) {
     echo $param;
  }
}
/*
===============================
 End of the loader class
==============================
*/

/*
===============================
 start of core controller class
==============================
*/

class Controller {

  private static  $instance;

  function __construct () {
    self::$instance = $this;
    $this->load = new Loader();
  }


  public static function get_instance(){
    return self::$instance;
  }
}
/*
===============================
end of the core controller class
=================================== 
*/

/*
 ====================================================
  start of library sections (put all your library classes in this section)
=====================================================
*/

class MyLibrary {

 private $c;

 function __construct() {
   $this->c = Controller::get_instance();
 }

 function say($sentence) {
   $this->c->load->view($sentence);
 }
}
/*
 ====================================================
  End of the library sections
====================================================
*/

/*
 ============================================
  start of controller section (put all your controller classes in this section)
 ===========================================
*/

class Foo extends Controller {

  function __construct () {
    parent::__construct();
    $this->load->_class('MyLibrary');
  }

  function bar() {
    $this->mylibrary->say('Hello World');
  }
}


/* 
 ==========================================
  End of the controller sections
 ==========================================
*/

$foo = new Foo();
$foo->bar();

Ответ 5

Только класс, который расширяет CI_Controller, Model, View может использовать

$this->load->library('something');
$this->load->helper('something');//..etc

Пользовательский класс не может использовать вышеуказанный код. Чтобы использовать вышеуказанные функции в своем пользовательском классе, вы должны использовать

$CI=&get instance();
$CI->load->library('something');
$CI->load->helper('something');

например, в вашем пользовательском классе

// this following code will not work
Class Car
{
   $this->load->library('something');
   $this->load->helper('something');
}

//this will work
Class Car
{
   $CI=&get_instance();
   $CI->load->library('something');
   $CI->load->helper('something');
}
// Here $CI is a variable.