Почему CodeIgniter не использует __autoload () (или spl_autoload_register)

Я недавно искал, как лучше всего организовать свои библиотеки / классы, и мне еще предстоит найти удовлетворительное решение. Это, и было бы намного чище написать $xyz = new XyzImplementation(), чем $xyz = $this->load->library('xyz_implementation'). И это только ухудшается с несколькими экземплярами, это кажется довольно ориентированным на использование библиотек / моделей в качестве синглтонов.

Почему CodeIgniter не использует только spl_autoload_register или __autoload()? Я знаю, что CI знает, где находятся файлы классов, поэтому не обязательно искать каждый раз, когда создается экземпляр класса. Это просто скорость? И / или сделать его легким? Если это так, то я хочу знать, какой метод лучше всего использовать для предоставления CI этой функциональности, то есть $xyz = new XyzImplementation().

Я пробовал HMVC, но мне не нравится, что он в основном удаляет ядро ​​CI_Loader и заново реализует каждую функцию. Мне интересно, что произойдет, если содержимое основных методов изменится ... Думаю, любой, кто использует HMVC придется ждать, пока он будет исправлен (или исправит его самостоятельно на github)

Сегодня вечером я придумал собственное решение, но не уверен, что оно настолько эффективно. Он в основном использует directory_map для поиска класса с соответствующим именем (например, XyzImplementation.php) в любом месте ниже APPPATH. Звучит ужасно, правда? Как только он найден XyzImplementation.php один раз, его местоположение кэшируется в файле и просто просматривается в следующий раз, поэтому после того, как сайт / приложение прошли небольшое тестирование, нет причин, по которым каждый экземпляр не будет поиском.

Похоже ли это на полуприличное решение? Предположим, что find_class_path возвращает полный относительный путь к найденному файлу класса, используя рекурсивный поиск в каталоге.

// ignore system classes
if('CI' === substr($name, 0, 2) || 'MY' === substr($name, 0, 2))
{
    return;
}

// read cache
$cache = array();
$cache_file = APPPATH.'cache/abracadabra.php';
$class_in_cache = false;
if(file_exists($cache_file))
{
    $cache_contents = file_get_contents($cache_file);
    if(!empty($cache_contents))
    {            
        $cache = unserialize($cache_contents);
        if(array_key_exists($name, $cache))
        {
            $class_in_cache = true;
            include_once($cache[$name]);
        }
    }
}

// class not in cache, find it in application
if(!$class_in_cache)
{
    // TODO be more restrictive than APPPATH
    $class_path = find_class_path($name, APPPATH);
    // TODO handle case where a class isn't found
    $cache[$name] = $class_path;
    file_put_contents($cache_file, serialize($cache)); // add to cache
    include_once $class_path;
}

// instantiate
if(class_exists($name)) // so as to not instantiate interfaces
{
    return new $name;
}

person Matthew    schedule 15.05.2011    source источник
comment
Я бы посоветовал вам подробнее остановиться на этом вопросе. На Почему нет нет ответа, и обычно его считают субъективным и аргументированным, но в остальной части вашего вопроса есть доля мяса, так что это было бы стыдно закрывать. Я думаю, вы получите лучшие ответы, если сосредоточитесь на интересной основной части, в настоящее время трудно понять, что это такое, и название не привлечет много зрителей.   -  person deceze♦    schedule 15.05.2011


Ответы (1)


Не будучи разработчиком CodeIgniter, я не могу сказать, почему они не используют __autoload или spl_autoload_register. Однако я могу придумать пару причин, по которым я не могу:

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

  • Использование синтаксиса $ this-> load-> library ('authentication') позволит более эффективно различать то, что именно загружается, будь то помощник, библиотека, модель и т. Д., И я думаю, что облегчит чтение вашего кода.

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

Честно говоря, я не нашел ничего беспорядочного в том, как CodeIgniter обрабатывает экземпляры классов. Я согласен с тем, что использование загрузчика CodeIgniter больше ориентировано на использование singleton-esque, однако, если вам нужно создать экземпляр класса, скажем, объекта человека, то почему бы просто не включить его, как любой обычный класс PHP? Фактически, если вы создаете экземпляры по причинам, связанным с вашими моделями, почему бы просто не использовать отличную структуру ORM?

person Jesse Bunch    schedule 15.05.2011
comment
Спасибо за ваши комментарии - особенно по запросу ввода-вывода для каждого экземпляра. Я мог бы (и буду) обойти это, кэшируя кеш как статическую переменную в этой функции, так что это только один запрос ввода-вывода на запрос страницы, я думаю, что это было бы приемлемо. - person Matthew; 15.05.2011