代码之家  ›  专栏  ›  技术社区  ›  Imq

PHP在类名前面加上用于自动加载的子空间

  •  1
  • Imq  · 技术社区  · 10 年前

    我只是绕着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;”时,为什么必须在extends类前面加上子空间“Lib”?接口也是如此。当我不准备时,我会收到一个自动加载错误。我正在使用composer自动加载并将其保存在composer.json中:

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

    在app/I中有子文件夹Lib、接口和控制器,如下所示:

    /app
        /Controllers
        /Interfaces
        /Lib
    

    我注意到,在其他开发人员代码中,他们不必这样做。我对自己做错了什么感到困惑。

    谢谢你的帮助。

    2 回复  |  直到 10 年前
        1
  •  2
  •   raidenace    10 年前

    您包括三个名称空间:

    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; 第一

        2
  •  1
  •   deceze    10 年前

    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\Bar use Foo\Bar as Bar 。因此,您正在创建别名 Bar 真正解析为全名 \Foo\Bar 自从 APP\Interfaces 在您的情况下不会解析到任何特定的接口,只使用 implements Interfaces 不会有任何意义。如果你只是使用 implements ControllerInterface ,解析到哪个命名空间将不明确。 \APP\Controllers\ControllerInterface ? \APP\ControllerInterface ? \APP\Lib\ControllerInterface ? 只是不清楚,无法自动解决。

    所以,你正在做的是缩短 APP\接口 为了正义 Interfaces ,然后参考 APP\Interfaces\ControllerInterface 只需使用较短的 Interfaces\ControllerInterface 。你可以这样做,使它更短:

    use APP\Interfaces\ControllerInterface;
    
    .. implements ControllerInterface ..