douling0053 2016-02-18 16:02
浏览 73
已采纳

PSR-4:自动加载器(编写器)和扩展名称空间确保回退php

I am having a problem with my namespace fallbacks and using PSR-4 loader in Composer.

What I am trying to do is this:

  1. Have a core which can overwritten / extended.
  2. The core is based off an interface.

The directory structure is like so:

site/app/View/Example.php
site/src/ACME/app/View/Example.php
site/src/ACME/app/Interface/View.php

I am not set on this configuration so if you have a better suggestion then go for it.

My composer json is like so for psr-4:

 "autoload": {
    "psr-4": {
         "ACME\\App\\Site\\" : "app/",
         "ACME\\App\\" : "src/AMCE/app/"
    }
}

I thought this would make ACME\App\Site\View fallback to ACME\App\View if the site one was not found (Note I haven't done the interface part yet...).

My code for site/app/View/Example.php is like so:

namespace ACME\App\Site\View;

class ViewExample extends View {

Which works, when I have site/app/View/View.php as well. That looks like:

namespace ACME\App\Site\View;

class View extends \ACME\App\View\View {

The site/src/app/View/View.php look like this:

namespace ACME\APP\View;

class View {

This one should use the interface (I haven't tried yet).

So what I really want to do is make it so I don't have to have site/app/View/View.php, and I don't have to have site/app/View/Example.php - it can use site/src/ACME/app/View/Example.php.

Sorry I'm new to namespaces so I may not of phrased it very well.

What I am getting at is I thought ACME\App\Site would fallback to ACME\App - it doesn't? Or I am doing it wrong? At the moment it needs all the files in place.

  • 写回答

3条回答 默认 最新

  • drrc61668568 2016-02-19 16:50
    关注

    Edit: Turns out I was originally wrong, it is possible to get your example working with PSR-4! You just need to specify an array of directories for namespaces that can be loaded from different places.

    Easy solution

    {
        "autoload": {
            "psr-4": {
                "ACME\\App\\Site\\": ["app/", "src/ACME/app"],
                "ACME\\App\\": "src/ACME/app/"
            }
        }
    }
    

    Personally, I would rather name my namespaces more explicitly, see below.

    Original Answer

    The composer PSR-4 loader does not fall back when trying to load files that do not exist. It just fails immediately. Its flow looks like:

    1. \ACME\App\Site\View is not loaded
    2. Scan PSR-4 entries for matching namespaces
    3. Class name matches the namespace \ACME\App\Site (your first PSR-4 entry).
    4. Load file app/View.php
    5. File does not exist. Error.

    It never goes back to step 3 and tries the next namespace.

    So how do I fix it?

    It looks like you want to separate your reusable library code from your site code. If that's the case, I would use separate namespaces. For example, use the ACME\Site namespace to hold your reusable code, and use ACME\MySiteName for your site-specific code. Then there will be no ambiguity, and composer will have no trouble loading your classes.

    But I don't want to rearrange my namespaces!

    Ok, that's fine, but you'll have to use a hack to get around your problem. Composer has a classmap loader, and you'll have to use that instead of the preferred PSR-4 loader.

    {
        "autoload": {
            "classmap": ["app/", "src/"]
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 券商软件上市公司信息获取问题
  • ¥100 ensp启动设备蓝屏,代码clock_watchdog_timeout
  • ¥15 Android studio AVD启动不了
  • ¥15 陆空双模式无人机怎么做
  • ¥15 想咨询点问题,与算法转换,负荷预测,数字孪生有关
  • ¥15 C#中的编译平台的区别影响
  • ¥15 软件供应链安全是跟可靠性有关还是跟安全性有关?
  • ¥15 电脑蓝屏logfilessrtsrttrail问题
  • ¥20 关于wordpress建站遇到的问题!(语言-php)(相关搜索:云服务器)
  • ¥15 【求职】怎么找到一个周围人素质都很高不会欺负他人,并且未来月薪能够达到一万以上(技术岗)的工作?希望可以收到写有具体,可靠,已经实践过了的路径的回答?