Composer autoload - 从父目录加载类

时间:2017-07-07 09:17:43

标签: php laravel composer-php psr-4

我目前正在开发一个需要从其父目录访问类的Laravel项目。

composer.json> PSR-4:

    "psr-4": {
        ...
        "ModuleA\\": "../ModuleA/baseObjects",
        "ModuleB\\": "../ModuleB/baseObjects"
    }

示例文件结构:

/var/www
 +- /xxx (project)
     +- /ModuleA
        +- /baseObjects
            - configClass.inc
     +- /ModuleB
        +- /baseObjects
            - configClass.inc
     +- /laravel
        - composer.json

我运行composer dump-autoload但该项目仍然无法找到ModuleA\configClass ModuleB\configClass

此外,在我的autoload_psr4.php中,上面引用如下:

'MobuleA\\' => array($baseDir . '/../MobuleA/baseObjects')
'MobuleB\\' => array($baseDir . '/../MobuleB/baseObjects')

提前谢谢。

5 个答案:

答案 0 :(得分:4)

PSR-4要求加载的文件具有命名空间类,并且命名空间结构必须匹配目录结构,相对于配置中定义的“基本目录”(http://www.php-fig.org/psr/psr-4/)。

因此,在文件var queryResult = from p in patients join i in illnesses on p.id equals i.id into allPatientIllnesses select new { Patient = p, IlnessList = allPatientIllnesses.ToList() }; foreach (var item in queryResult) { Citizen patient = item.Patient; string illnesses = string.Join(",", item.IlnessList.Select(i => i.illnessName)); } 中应该是类

/var/xxx/ModuleA/baseObjects/configClass.inc

然后在namespace ModuleA\baseObjects; class configClass { ... } 你可以

var/www/laravel/composer.json

这意味着:“目录 "psr-4": { "App\\": "app/", "ModuleA\\": "../ModuleA" } 应该是../ModuleA命名空间的根目录,然后通过匹配子目录来跟踪子名称空间”。

答案 1 :(得分:1)

您遇到的问题与父目录无关。实际上,您的Composer.json自动加载配置对于您的目录结构是正确的。

问题是.inc文件扩展名,它与PSR-4规范不兼容。更多信息:How To Make Composer (PSR-4) To Work With ".class.php" Extension?

如果您无法更新源代码以符合PSR-4规范,则可以使用Class Mapping

  

在安装/更新期间,类图引用全部合并为单个键=>值数组,可以在生成的文件vendor/composer/autoload_classmap.php中找到。通过扫描给定目录/文件中所有.php.inc文件中的类来构建此映射。

     

您可以使用类映射生成支持为不遵循PSR-0/4的所有库定义自动加载。要配置它,请指定要搜索类的所有目录或文件。

所以你的配置可能如下:

"autoload": {
    "classmap": [
        "../ModuleA/baseObjects",
        "../ModuleB/baseObjects"
    ]
}

请记住,如果您使用类映射,则每次更改composer dump-autoload,添加类,修改类名称/文件名/路径等时都需要运行composer.json

@alepeino指出

额外:,使用autoloader optimization将使用相同的基础代码{{}从任何PSR-0和PSR-4自动加载定义生成类映射1}}自动加载使用。这将“允许”您使用PSR-4自动加载器和classmap扩展名。每次更改文件时,仍然需要运行.inc,就像类图一样。

最佳建议:更改源代码以遵循PSR-4规范,并使用composer dump-autoload --optimize扩展名。

接下来最好不要这样做:使用.php进行自动加载。

答案 2 :(得分:0)

试一试:

"psr-4": {
        ...
        "ModuleA\\": "ModuleA/baseObjects",
        "ModuleB\\": "ModuleB/baseObjects"
 }

答案 3 :(得分:0)

根据此answer,您可以将其添加到index.php文件中:

$loader = require 'vendor/autoload.php';
$loader->add('Namespace\\Somewhere\\Else\\', __DIR__);
$loader->add('Namespace\\Somewhere\\Else2\\', '/var/www/html/xxx');

答案 4 :(得分:0)

使用classmap autoload将解决此问题。

{
...
"autoload": {
        "classmap": ["ModuleA/", "ModuleB/"]
    }
}

它可以与PSR-4一起使用

{
    ...
    "autoload": {
            "psr-4": { 
                "Acme\\": "src/Acme/"
            },
            "classmap": ["ModuleA/", "ModuleB/"]
        }
    }

参考:https://getcomposer.org/doc/04-schema.md#classmap