我最近一直在研究如何最好地组织我的图书馆/课程,我还没有想出一个满意的解决方案。写$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;
}
答案 0 :(得分:2)
不是CodeIgniter的开发者,我不能说他们为什么不使用__autoload
或spl_autoload_register
。但是,我可以想到 I 可能没有的几个原因:
某些操作码缓存不支持自动加载。对于将在生产中的各种服务器上使用的产品,这将是一个疏远的错误,并可能导致实质性的性能损失,其中,速度是CodeIgniter的主要吸引力。
使用$ this-> load->库('authentication')语法可以更有效地区分正在加载的内容,无论是帮助程序,库,模型等,我认为使您的代码更易于阅读。
关于自动加载类的实现,假设所有使用过的类都缓存在缓存文件中。您正在为执行的每个类实例添加额外的IO请求和不必要的内存使用量。如果您认为您的应用程序将达到企业级别,那就是可以回过头来获得这种开销。在你变大之前考虑这些事情是很好的,它会在以后为你节省心痛和金钱。
说实话,我发现CodeIgniter处理类实例化的方式没什么问题。我同意使用CodeIgniter加载器更适合单例式使用,但是如果你需要实例化一个类的实例,比如一个person对象,那么为什么不像普通的PHP类一样包含它呢?事实上,如果您因为与模型有关的原因进行实例化,为什么不使用一个优秀的ORM框架呢?