получить instance () в Codeigniter: зачем назначать его переменной?

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

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 в вашей библиотеке используйте

7 ответов


насколько я знаю, это вопрос больше удобства, чем ничего. Скорее всего, вы будете использовать CI super object много в своих библиотеках, так почему бы не назначить его переменной, чтобы сделать его немного проще работать?

есть несколько других вещей, чтобы рассмотреть...

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

почему рекомендуется назначить get_instance() переменной, а не чем звонить напрямую?

скорее всего, рекомендуется поддерживать обратную совместимость с php4, где объекты по умолчанию не передавались по ссылке, а клонировались.

есть ли причина не использовать этот подход?

только если вы хотите, чтобы ваше приложение работало на устаревших установках php


необходимо назначить по ссылке, потому что значение CI_Controller::$instance может измениться, если будет создан другой экземпляр класса. Конструктор повторно назначает self::$instance каждый раз, когда он работает.

В общем, это похоже на плохой шаблон дизайна и отсутствует свойство синглтона, которое ограничивает класс только одним экземпляром,http://en.wikipedia.org/wiki/Singleton_pattern.

кажется, можно типа CI_Controller::get_instance()->$className->$method(); что кажется больше введите, что ваш запрошенный CI()->$className->$method.

в конечном счете, имело бы смысл требовать, чтобы только один экземпляр $instance может быть создан, а затем необходимость назначения по ссылке будет устранена.


метод цепочки не поддерживается в PHP4 и CI прекращена поддержка PHP4 совсем недавно (с версии 2.0.0). Также легко написать $CI чем писать get_instance() каждый раз.


Я предпочитаю использовать этот способ, это просто

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

это может быть комбинация нескольких вещей, включая уже упомянутые:

  • обратной совместимости
  • удобство
  • Гид По Стилю

предпочтительно, мне нравится идея этой "рекомендации" как части руководства по стилю. Может быть, не официальное руководство по стилю CI, но все же.

представьте, что все сторонние скрипты для CI реализуют эту рекомендацию, любой разработчик сможет быстро определите, как эти сценарии разработаны - хотя это всего лишь очень небольшая часть сценария.

другое дело, что ИМО-это важный механизм цепочкой и делаю CI()->class->method() не кажется интуитивным для меня, зная, как работает остальная часть CI.


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

для тех, кто заинтересован, вот über быстрый экземпляр getter:

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

    return $CI;
}

обратите внимание, что статическая переменная не будет работать, если она была назначена по ссылке.

кроме того, вы вынуждены не получать по ссылке результат этого CI(). Дополнительный сахар :-)

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