Я недавно искал, как лучше всего организовать свои библиотеки / классы, и мне еще предстоит найти удовлетворительное решение. Это, и было бы намного чище написать $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;
}