带有扩展或接口的命名空间会导致致命错误而不使用自动加载器

时间:2017-04-15 13:31:53

标签: php oop namespaces

为什么这不起作用?

web / index.php (不是web/src/App/App.php

<?php

namespace App;

// web/index.php
require_once __DIR__ . '/../vendor/autoload.php';

$app = new App();

class App extends \Silex\Application {
    public function __construct()
    {
        parent::__construct();

        echo 'Worked!';
    }
}

我也试过namespace App {...},没有变化。它抛出了这个例外:

Fatal error:  Uncaught Error: Class 'App\App' not found in /path/to/web/index2.php:8
Stack trace:
  #0 {main}
  thrown in /path/to/web/index2.php on line 8

只要删除extends ...parent来电部分,就可以了。我还注意到interface做了同样的事情(尝试使用Serializable)。这是自动加载器混淆的问题吗?有没有办法在不将App\App类放入src\App\App.php的文件中的情况下执行此操作?

注意:这是一个用Silex构建单文件应用程序的练习,所以“只是将它放在一个文件中”不是答案。我想知道为什么这不起作用,这有一个答案。

1 个答案:

答案 0 :(得分:1)

代码中的问题是,

在命名空间中,您在声明和加载之前启动类对象。在上面的代码中,你正在做同样的事情,

1。您正在发起位于App命名空间的App类对象

2。当您尚未声明时,您正在启动类对象(如下面的代码中所定义)。

在上面的代码中,甚至不会调用您的加载程序。如果在声明后启动App\App类对象,则会调用它。如果您的加载器不能正常工作,那么之后您可能会收到此错误。

  

致命错误:未找到Silex \ Application

请查看一些示例和结果。

Example 1这里加载器应该被调用但不被调用,因为你在初始化类($app = new App();)之后注册了。

Example 2这里,调用类将查找自动加载类,因为这里初始化发生在加载器注册和类声明之后,这可能会回答你的问题。

使用此代码更改代码以解决问题:

<?php

namespace App;

require_once __DIR__ . '/../vendor/autoload.php';

class App extends \Silex\Application {
    public function __construct()
    {
        parent::__construct();

        echo 'Worked!';
    }
}

$app = new App();