Автозагрузка 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/"]
}
}
Проблема, с которой вы столкнулись, не связана с родительскими каталогами. Фактически, ваша конфигурация автозагрузки 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"
}