PHP - require_once和类继承问题

时间:2013-09-06 19:28:34

标签: php class require-once

我收到致命错误:Fatal error: Class 'Foo1' not found in .../Foo2.php on line 5包含以下文件:

的index.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 {
}

Bar.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语句时,此代码有效?

  3. 更新 提出的大多数解决方案涉及自动加载。不幸的是,我的问题在于一个包含大量现有代码和许多不良实践的旧项目。我们真的远离PSR-0标准。

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

3 个答案:

答案 0 :(得分:1)

  1. 使用autoloading功能。在包含类定义的文件中不要有任何其他可执行代码(如require / include)。
  2. 因为当Foo1实现IFoo时,php对IFoo一无所知,因此无法注册类Foo1。由于没有注册自动加载器,php开始解释代码,省略Foo1.php的类声明,直到包含和解析其他文件。当它达到Foo2.php时,它不包括Foo1.php(由于require_once)并开始解释文件 - 这里遇到类Foo1,由于不存在而跳过了定义那时接口实现。此时php并不知道Foo1是在已经需要的Foo1.php中声明的,因为它没有机会完全解释这个文件。

答案 1 :(得分:0)

我建议使用Autoloading Standard PSR-0。它描述了自动加载器互操作性必须遵守的强制性要求。

无论如何在这种情况下:

<强> Foo1.php

您包括Bar.php,由于此行:require_once('./Foo2.php');Class Foo2延伸Class Foo1。但是类Foo1尚未定义!您只能在定义后扩展类。

所以似乎require_once('./Foo2.php');不应该在Bar.php中。或者您应该在require_once('./Bar.php');定义后移动class Foo1

<?php
require_once('./IFoo.php');

class Foo1 implements IFoo
{
    /** @var  Bar */
    private $bar;
}

require_once('./Bar.php');

答案 2 :(得分:0)

如果您将Foo1.php文件修改为此

<?php
require_once('./IFoo.php');

class Foo1 implements IFoo
{
/** @var  Bar */
private $bar;
}

require_once('./Bar.php');

?>

这很有效。

原因是PHP是解释语言(解释器逐行执行脚本)。 因此,在您的情况下,解释器在Foo2.php中遇到未定义的类Foo1时会错过Foo1声明语句并引发错误。