我可以帮忙翻译中文。以下是需要翻译的内容:
PHP的spl_autoload_register如何通过require_once解决循环依赖?
在某些情况下,循环依赖可以被解决,但并非所有情况都适用。让我们从一个失败的例子开始。假设我们有三个类定义在不同的文件中:
cat.php
class Cat extends Animal {}
animal.php
require_once('cat.php');
class Animal extends Creature {}
creature.php
class Creature {}
假设我们还有一个自动加载器并创建Animal实例的脚本: run.php
spl_autoload_register(function($className) {
require_once("$className.php");
});
$a = new Animal();
使用"php run.php"运行此脚本将导致PHP致命错误:
PHP致命错误:在.../Cat.php中找不到类'Animal'
我认为这对我来说很直观,因为动物和猫之间存在循环依赖:
- 自动加载程序尝试加载animal.php
- 由于require_once()的原因,加载animal.php会导致cat.php被加载
- 加载cat.php失败,因为它扩展了Animal,并且Animal不能被自动加载程序加载两次。
以下是一些修改,以确保我们不会出现致命错误
- animal.php不应该有require_once('cat.php')
- 这似乎是最好的解决方案,因为它有效地消除了Animal和Cat之间的循环依赖关系
- Animal类不应该扩展Creature
- 不要在run.php中使用Autoloader,只需对animal.php和creature.php使用require_once()
问题:
- 为什么#2起作用?为什么Animal不扩展Creature会导致Animal和Cat之间的循环依赖关系得到解决?
- 为什么#3起作用?自动加载程序不只是在幕后执行require_once()吗?
此示例的完整代码(带有一些附加日志记录)可以在此处找到。