php - __autoload 的最佳解决方案

标签 php oop autoload

随着我们的 PHP5 OO 应用程序的增长(大小和流量),我们决定重新审视 __autoload() 策略。

我们总是根据文件包含的类定义来命名文件,因此类 Customer 将包含在 Customer.php 中。我们曾经列出文件可能存在的目录,直到找到正确的 .php 文件。

这是非常低效的,因为您可能会遍历许多不需要的目录,并且在每次请求时都这样做(因此,会产生大量的 stat() 调用)。

我想到的解决方案...

- 使用指定目录名称的命名约定(类似于 PEAR)。缺点:不能扩展太大,导致可怕的类名。

- 想出某种预先构建的位置数组(propel 为它的 __autoload 做这个)。缺点:在部署任何新代码之前需要重建。

-“即时”构建数组并缓存它。这似乎是最好的解决方案,因为它允许您使用任何您想要的类名和目录结构,并且在新文件刚刚添加到列表中时非常灵活。关注点是:将其存储在何处以及删除/移动的文件如何处理。对于存储,我们选择了 APC,因为它没有磁盘 I/O 开销。关于文件删除,这无关紧要,因为您可能不想在任何地方都需要它们。至于移动......那是悬而未决的(我们忽略它,因为历史上它对我们来说并不经常发生)。

还有其他解决方案吗?

最佳答案

我也玩了很长时间的自动加载,最后我实现了某种命名空间自动加载器(是的,它也适用于 PHP5.2)。

策略很简单: 首先,我有一个单例类(加载器),它有一个模拟 import 的调用。此调用采用一个参数(要加载的完整类名)并在内部计算调用它的文件名(使用 debug_backtrace())。该调用将此信息存储在关联数组中以供稍后使用(使用调用文件作为键,并为每个键使用导入类的列表)。

典型的代码如下所示:

<?php

    loader::import('foo::bar::SomeClass');
    loader::import('foo::bar::OtherClass');

    $sc = new SomeClass();

?>

当自动加载被触发时,存储在数组中的完整类名被转换为一个真实的文件系统位置(双冒号被目录分隔符替换),并包含生成的文件名。

我知道这不完全是你想要的,但它可以解决目录遍历问题,因为加载器直接知道文件的确切位置(增加的功能是你可以在目录中组织你的类,用没有明显的性能损失)。

我可以为您提供一些工作示例,但我太害羞了,不敢向公众展示我糟糕的代码。希望上面的解释有用...

关于php - __autoload 的最佳解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/359829/

相关文章:

php - 嵌套 foreach 循环的错误

php - 比较另一个表中是否存在记录

java - 对具有相同特定实例变量的对象 [在对象数组内] 的实例变量求和

php - Yii 自动加载自定义组件

php - 动态加载命名空间类

javascript - 自动加载随机页面

javascript - 如何禁用youtube提供的右键单击选项

php - 是否有匹配 "string"和 "Object that implements __toString()"的 native 接口(interface)?

php - 计算创建 PHP 类的次数

c++ - 使用其行为之一来修改整个对象是否有意义?在赋值运算符内部使用 this 指针进行重载?