Автозагрузка Composer - загрузка класса из родительского каталога

В настоящее время я работаю над проектом 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 ответов

PSR-4 требует, чтобы у загруженных файлов был класс пространства имен, а структура пространства имен должна соответствовать структуре каталогов относительно "базового каталога", определенного в конфигурации ( http://www.php-fig.org/psr/psr-4/).

Итак, в файле /var/xxx/ModuleA/baseObjects/configClass.inc должен быть классом

namespace ModuleA\baseObjects;

class configClass {
    ...
}

Затем в var/www/laravel/composer.json ты мог бы иметь

    "psr-4": {
        "App\\": "app/",
        "ModuleA\\": "../ModuleA"
    }

Что означает: "каталог ../ModuleA должен быть корнем для ModuleA namespace, затем следуйте подпространствам, сопоставляя оттуда подкаталоги ".

Использование автозагрузки classmap решит эту проблему.

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

Может использоваться с PSR-4

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

Ссылка: https://getcomposer.org/doc/04-schema.md#classmap

Проблема, с которой вы столкнулись, не связана с родительскими каталогами. Фактически, ваша конфигурация автозагрузки Composer.json соответствует вашей структуре каталогов.

Проблема заключается в .inc расширение файла, которое несовместимо со спецификацией PSR-4. Подробнее здесь: Как заставить Composer (PSR-4) работать с расширением ".class.php"?

Если вы не можете обновить свой исходный код в соответствии со спецификацией 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, использование оптимизации автозагрузчика сгенерирует карту классов из любых определений автозагрузки PSR-0 и PSR-4, используя тот же базовый код, который classmap автозагрузка использует. Это позволит вам использовать автозагрузчик PSR-4 и .inc расширение. Это все равно потребует от вас запуска composer dump-autoload --optimize однако каждый раз, когда вы вносите изменения в файл, как в classmap.

Лучшая рекомендация: измените исходный код в соответствии со спецификациями PSR-4 и используйте .php расширение.

Лучше всего, если вы не можете этого сделать: используйте classmap для автозагрузки.

Согласно этому ответу вы можете добавить его в файл index.php:

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

Попытайся:

"psr-4": {
        ...
        "ModuleA\\": "ModuleA/baseObjects",
        "ModuleB\\": "ModuleB/baseObjects"
 }
Другие вопросы по тегам