PHP - require_once和类继承问题


PHP - require_once and class inheritance issue

我收到一个致命错误: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
{
}

问题:

  1. 如何解决这种情况?
  2. 为什么当我抑制implements IFoo语句时,这段代码有效?

更新提出的大多数解决方案都涉及自动加载。不幸的是,我的问题出在一个旧项目上,该项目有很多现有代码和很多糟糕的做法。我们离PSR-0标准还很远。

在性能方面引入自动加载的成本是多少?

  1. 使用自动加载功能。不要在带有类定义的文件中使用任何其他可执行代码(如require/include)。
  2. 因为当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');