如何使用spl_autoload()代替__autoload()

50

根据http://php.net/manual/en/language.oop5.autoload.php,魔术函数__autoload()在PHP 7.2.0中被标记为过时,在PHP 8.0.0中已经被删除。

官方的替代方案是spl_autoload()。详情请参见http://www.php.net/manual/en/function.spl-autoload.php。但是PHP手册并没有解释这个函数的正确使用方式。

我的问题:如何用spl_autoload()替换我的自动类自动加载器?

function __autoload($class) {
    include 'classes/' . $class . '.class.php';
}

问题:我无法弄清如何为该函数提供一个路径(它只接受命名空间)。

顺便说一下,在SO上有很多关于这个主题的线程,但没有一个能给出一个干净简单的解决方案来替换我的性感一行代码。


2
我已经将一个基本示例添加到了PHP文档中,该示例基于上面的示例。希望这样的内容在未来不会难以找到。 - salathe
PHP手册一点也不糟糕。 - Shikiryu
1
@Shikiryu 嗯,说实话,确实如此。在大多数情况下,很难理解某个东西的工作原理,因为文档是由一些彻头彻尾的极客编写的。即使你知道某个东西的工作原理,也不可能理解官方文档。更糟糕的是,在大多数情况下,官方文档还被大量的注释所修正和重写。像mysqli、cookies或sessions这样的东西非常难找到,而且更难理解。如果你按照示例来做,你会失败的。这是IT和开源领域的一个普遍问题:缺乏可用性。 - Sliq
我完全是诚实的。这份文档对我来说似乎很清晰。例如,对于这个特定的问题,所选择的答案都写在了你提供的页面的“提示”部分中...但现在,我刚刚看到你提问已经快一年了,所以可能已经有所改变。 - Shikiryu
1个回答

83

你需要使用spl_autoload_register来注册自动加载函数。你需要提供一个"可调用的"参数。从PHP5.3及以后的版本中,使用匿名函数是最好的方法:

spl_autoload_register(function($class) {
    include 'classes/' . $class . '.class.php';
});
这种方法与__autoload相比的主要优势是,您可以多次调用spl_autoload_register,而__autoload(像任何函数一样)只能定义一次。如果您的代码模块化,那么这将是一个重大缺点。
更新于2018年:实际上不应该有那么多情况需要自己编写自动加载器。有一个被广泛接受的标准(称为PSR-4),以及几个符合标准的实现方式。显而易见的做法是使用Composer

3
值得一提的是,将您的自动加载器采用 PSR-0 标准可能是一个不错的主意(除了保留旧的 PEAR 约定的遗留支持)。如果您正在编写自己的自动加载器,这会使它与某些更大型和流行的框架非常兼容。如果您不想编写自己的自动加载器,但使用指定的命名/存储约定,则可以使用现有的自动加载器组件。 - prodigitalson
@lonesomeday 谢谢,这是一个完美的解决方案,可以100%替代上面的autoload()。 - Sliq
请查看此处的答案补充:https://pt.stackoverflow.com/questions/292270/fatal-error-cannot-redeclare-spl-autoload-register - Leffa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接