В 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 super объект.Обычно из функций контроллера вы вызываете любой из доступные функции CodeIgniter с использованием конструкции
$this
:$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- > помощник ( 'URL'); $CI- > load- > библиотека ( 'сессии'); $ CI- > config- > пункт ( '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()
напрямую? Кажется, что присвоение всего объекта 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, и я использую их, когда это необходимо, но я никогда не видел функцию, определенную таким образом. Если я пишу функцию обертки, должен ли я использовать ее также?
Обратите внимание, что это не столько вопрос стиль, но технический. Я хочу знать, есть ли какие-либо проблемы, производительность или нет, используя метод, который я предлагаю.
EDIT: До сих пор мы имеем:
- Цепочка метода недоступна в php4, поэтому присвоение переменной является обходным решением (хотя это довольно неуместно, поскольку Codeigniter отказался от поддержки php4)
- Небольшие служебные данные для вызова функции более одного раза для возврата объекта, а не вызова его один раз и назначения переменной.
Что-нибудь еще, или это единственные потенциальные проблемы?