Загрузка и обнаружение NextPDF Artisan
Artisan — обычная библиотека, которая следует рекомендации PHP Standard Recommendation 4 (PSR-4). У неё нет ни сервис-провайдера, ни bundle, ни манифеста автообнаружения фреймворка. Она загружается, как только её классы становятся доступны автозагрузчику. Обнаружение здесь — это карта PSR-4 в Composer, и ничего более.
Как работает обнаружение
Заголовок раздела «Как работает обнаружение»Файл composer.json пакета объявляет два корня PSR-4: NextPDF\Artisan\ → src/Artisan/ и NextPDF\Parser\ → src/Parser/. В нём нет ни extra.laravel, ни класса bundle для Symfony, ни регистратора для CodeIgniter. Во время загрузки ничего не сканируется, не регистрируется и не подключается через хуки.
Точка интеграции находится в nextpdf/core. Document (через трейт HasTextOutput) предоставляет метод writeHtmlChrome(), который во время выполнения проверяет class_exists() для NextPDF\Parser\PdfReader и NextPDF\Artisan\PageImporter. Если автозагрузчик может разрешить оба класса, путь Chrome доступен. Если не может, core выбрасывает исключение макета вместо аварийного завершения с фатальной ошибкой. По сути, обнаружение сводится к одному вопросу: зарегистрированы ли классы Artisan в автозагрузчике? Ответ даёт Composer; механизмы фреймворка здесь не участвуют.
Это сделано намеренно. Мост — это возможность, к которой ядро движка обращается через границу пакета, а не сервис под управлением фреймворка. Artisan одинаково работает в Laravel, Symfony, CodeIgniter, CLI-скрипте или обработчике очереди, потому что ни одна из этих сред ему не требуется.
Последовательность загрузки
Заголовок раздела «Последовательность загрузки»У Artisan нет ни загрузочного ядра, ни регистрации команд, ни фазы отложенных провайдеров. Первый вызов writeHtmlChrome() и есть вся точка входа в жизненный цикл.
Привязки контейнера
Заголовок раздела «Привязки контейнера»У Artisan нет контейнера внедрения зависимостей (DI), и он не регистрирует никаких привязок. Его компоненты — обычные объекты, внедряемые через конструктор: создайте ChromeRendererConfig, передайте его в ChromeHtmlRenderer и при необходимости внедрите логгер PSR-3 и собственный HtmlSecurityPolicyInterface. В контейнере хостовой среды зарегистрируйте ChromeHtmlRenderer как singleton самостоятельно; см. пример на /integrations/artisan/production-usage/.
Разрешение сервисов без контейнера
Заголовок раздела «Разрешение сервисов без контейнера»Некоторые возможности NextPDF, включая контракты e-invoice уровня Premium, обычно разрешаются через контейнер фреймворка. Artisan также работает в средах без контейнера: инструментах CLI, автономных скриптах и пользовательских исполнителях. Поэтому он поставляется с EInvoiceServiceFactory:
| Метод | Возвращает | Когда null |
|---|---|---|
makeEmbedder() | EmbedderInterface (уровень Pro) | Уровень Pro не установлен |
makeValidator() | ValidatorInterface (уровень Enterprise) | Уровень Enterprise не установлен |
makeDefaultProfile() | ProfileInterface (EN16931, уровень Pro) | Уровень Pro не установлен |
makeSchematronRunner() | SchematronRunnerInterface (уровень Enterprise) | Уровень Enterprise не установлен |
Каждый вызов возвращает новый экземпляр. Такая одноразовая выдача важна, поскольку вызовы embed и validate владеют изменяемым контекстом разбора Extensible Markup Language (XML) и не должны разделять состояние. Фабрика — удобство для редкого сценария без контейнера, а не локатор сервисов. Предпочтительный шаблон по-прежнему — собирать объекты при создании и передавать их как аргументы конструктора. Возврат null при отсутствии уровня повторяет поведение пакетов-обёрток для фреймворков, поэтому один и тот же вызывающий код работает и с Premium, и без него. Источник: src/Artisan/EInvoiceServiceFactory.php; интеграционно протестировано в tests/Integration/Artisan/EInvoiceServiceFactoryIntegrationTest.php.
Порядок разрешения конфигурации
Заголовок раздела «Порядок разрешения конфигурации»Каскада конфигурационных файлов нет. Конфигурация — это ровно то, что вы передаёте в ChromeRendererConfig:
- Аргументы конструктора, которые вы передаёте явно, либо
ChromeRendererConfig::fromArray()из массива, предоставленного хостовой средой (ключи в snake-case; неустановленные ключи возвращаются к значениям конструктора по умолчанию;chrome_binaryприменяется только тогда, когда это непустая строка).
Разрешённая конфигурация неизменна в течение всего времени жизни рендерера. Все ключи см. на /integrations/artisan/configuration/.
Диагностика
Заголовок раздела «Диагностика»- “Обнаруживается ли мост?” — если
class_exists(\NextPDF\Artisan\PageImporter::class)возвращаетtrue, автозагрузчик Composer может найти мост, и core будет использовать путь Chrome. - “Загрузился ли он?” — фазы загрузки, которая могла бы завершиться ошибкой, нет; отсутствующая зависимость проявляется при первом вызове
writeHtmlChrome()как типизированное исключение, сопоставленное на /integrations/artisan/troubleshooting/. - Проверка Premium без контейнера —
EInvoiceServiceFactory::makeEmbedder() === nullозначает, что уровень Pro не установлен; путь отрисовки с открытым исходным кодом при этом не затрагивается.
См. также
Заголовок раздела «См. также»- /integrations/artisan/integration/ — интеграция
- /integrations/artisan/overview/ — обзор
- /integrations/artisan/configuration/ — настройка
- /integrations/artisan/production-usage/ — использование в продакшене
- /integrations/artisan/troubleshooting/ — устранение неполадок