我收到一个致命错误:Fatal error: Class 'Foo1' not found in .../Foo2.php on line 5
以下文件:
索引.php:
<?php
require_once("./Foo1.php");
?>
<h1>Success</h1>
Foo1.php:
<?php
require_once('./IFoo.php');
require_once('./Bar.php');
class Foo1 implements IFoo
{
/** @var Bar */
private $bar;
}
IFoo.php:
<?php
interface IFoo {
}
酒吧.php:
<?php
require_once('./Foo2.php');
class Bar {
/** @var Foo2 */
private $foo;
}
Foo2.php:
<?php
require_once("./Foo1.php");
class Foo2 extends Foo1
{
}
问题:
- 如何解决这种情况?
- 为什么当我抑制
implements IFoo
语句时,这段代码有效?
更新提出的大多数解决方案都涉及自动加载。不幸的是,我的问题出在一个旧项目上,该项目有很多现有代码和很多糟糕的做法。我们离PSR-0标准还很远。
在性能方面引入自动加载的成本是多少?
- 使用自动加载功能。不要在带有类定义的文件中使用任何其他可执行代码(如
require
/include
)。 - 因为当
Foo1
实现IFoo
时,php对IFoo
一无所知,所以它不能注册类Foo1
。 由于没有注册自动加载器,PHP 开始解释代码,省略Foo1.php
中的类声明,直到包含和解析其他文件。当它到达Foo2.php
时,它不包括Foo1.php
(由于require_once
)并开始解释文件 - 在这里它遇到了类Foo1
由于当时不存在接口实现而被跳过的定义。在这一点上,php不知道Foo1是在已经需要的Foo1.php
中声明的,因为它没有机会完全理解这个文件。
如果将 Foo1.php 文件修改为此
<?php
require_once('./IFoo.php');
class Foo1 implements IFoo
{
/** @var Bar */
private $bar;
}
require_once('./Bar.php');
?>
这行得通。
原因是PHP是解释语言(解释器逐行执行脚本)。因此,在您的情况下,解释器会错过 Foo1 声明语句,并在遇到 Foo2.php 中未定义的类 Foo1 时引发错误。
我建议使用自动加载标准PSR-0。它描述了自动加载机互操作性必须遵守的强制性要求。
无论如何,在这种情况下:
福1.php
您包括Bar.php
,并且由于这一行:require_once('./Foo2.php');
,Class Foo2
扩展Class Foo1
。但是Foo1
类还没有定义!只有在定义 It 之后才能扩展类。
所以似乎require_once('./Foo2.php');
不应该在Bar.php
.或者,您应该在定义class Foo1
之后移动require_once('./Bar.php');
。
<?php
require_once('./IFoo.php');
class Foo1 implements IFoo
{
/** @var Bar */
private $bar;
}
require_once('./Bar.php');