PHP在子空间前面添加类名以进行自动加载

时间:2014-07-30 18:46:56

标签: php namespaces autoload

我只是围绕PHP命名空间和使用composer进行自动加载。我对以下代码有疑问:

namespace APP\Controllers;

use APP;
use APP\Interfaces;
use APP\Lib;

class      PageController 
extends    Lib\ActionController 
implements Interfaces\ControllerInterface 
{
    //stuff
}

当我已经使用'use APP \ Lib;'这一行时,为什么我必须在子空间前加上'Lib \'来扩展extends类?接口也是如此。当我没有前置时,我得到一个自动加载错误。我正在使用composer进行自动加载,并在我的composer.json中使用它:

"autoload": {
    "psr-4": {
        "APP":        "app/"
    }
}

在app /我有子文件夹Lib,Interfaces和Controllers之类的:

/app
    /Controllers
    /Interfaces
    /Lib

我注意到在其他开发代码中他们不必这样做。我很困惑我做错了什么。

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您包含三个名称空间:

use APP;
use APP\Interfaces;
use APP\Lib;

现在,如果你只是说:

extends ActionController 

PHP不知道是否:

APP\ActionController or
APP\Interfaces\ActionController or
APP\Lib\ActionController

如果您仍希望在没有Lib子空间的情况下扩展它,则需要执行以下操作:

首先

use APP\Lib\ActionController;

答案 1 :(得分:1)

use只有别名名称空间或短名称的类名。这是为了避免必须始终按照其完全限定名称重复处理所有类:

$a = new \Foo\Bar\Baz\Quurx();
$b = new \Foo\Bar\Baz\Quurx();

// shorter:

use Foo\Bar\Baz\Quurx;

$a = new Quurx();
$b = new Quurx();

use Foo\Baruse Foo\Bar as Bar的简写。因此,您正在创建一个真正解析为全名Bar的别名\Foo\Bar。由于APP\Interfaces无法解析您的案例中的任何特定界面,因此仅使用implements Interfaces并不意味着什么。如果您刚刚使用implements ControllerInterface,则解析为哪个命名空间将是不明确的。 \APP\Controllers\ControllerInterface\APP\ControllerInterface\APP\Lib\ControllerInterface?它只是不清楚,无法自动解决。

所以,你正在做的是将APP\Interfaces简化为Interfaces,然后仅使用较短的APP\Interfaces\ControllerInterface来引用Interfaces\ControllerInterface。你可以做到这一点,使它更短:

use APP\Interfaces\ControllerInterface;

.. implements ControllerInterface ..