Загрузка NextPDF в Laravel и автообнаружение
Краткий обзор
Заголовок раздела «Краткий обзор»Laravel автоматически обнаруживает NextPdfServiceProvider из composer.json пакета. Провайдер регистрирует отложенные привязки контейнера и публикует файл конфигурации в консольном контексте. На этой странице объясняется, как работает обнаружение и как долго живёт каждая привязка.
Установка
Заголовок раздела «Установка»composer require nextpdf/laravelphp artisan vendor:publish --tag=nextpdf-configКак работает автообнаружение в Laravel
Заголовок раздела «Как работает автообнаружение в Laravel»Пакет объявляет провайдер и псевдоним фасада в блоке extra.laravel собственного composer.json:
{ "extra": { "laravel": { "providers": [ "NextPDF\\Laravel\\NextPdfServiceProvider" ], "aliases": { "Pdf": "NextPDF\\Laravel\\Facades\\Pdf" } } }}Когда вы выполняете composer require, Laravel читает этот блок, а затем регистрирует провайдер и псевдоним. Вам не нужно вручную править config/app.php или bootstrap/providers.php. Массив extra.laravel.providers автоматически регистрирует провайдеров служб, а extra.laravel.aliases — псевдонимы фасадов (руководство по разработке пакетов Laravel 12,
https://laravel.com/docs/12.x/packages, получено 2026-05-18).
Последовательность загрузки
Заголовок раздела «Последовательность загрузки»NextPdfServiceProvider реализует DeferrableProvider и стандартный жизненный цикл register() / boot().
register()объединяет конфигурацию пакета под ключомnextpdf. Затем он привязывает записи контейнера: реестр шрифтов, реестр изображений, фабрику документов, клиент Hypertext Transfer Protocol (HTTP) по PHP Standards Recommendation 18 (PSR-18), клиент меток времени, подписывающий компонент, документ и контракты электронных счетов. Каждая привязка — это замыкание, поэтому здесь не создаётся ничего ресурсоёмкого.boot()проверяет, что расширения PHPmbstringиzlibзагружены. Он регистрирует публикуемую конфигурацию под тегомnextpdf-configтолько тогда, когдаrunningInConsole()возвращает true.
Поскольку провайдер работает отложенно, register() выполняется только тогда, когда вы разрешаете одну из записей, возвращаемых provides(). Разрешение несвязанного ключа контейнера не загружает NextPDF.
Привязки контейнера и время их жизни
Заголовок раздела «Привязки контейнера и время их жизни»PHP Standards Recommendation 11 (PSR-11) допускает, что два последовательных вызова get() с одним и тем же идентификатором возвращают разные значения в зависимости от стратегии привязки (PSR-11 §1.1.2). Провайдер намеренно опирается на это поведение:
| Ключ привязки | Время жизни | Примечания |
|---|---|---|
FontRegistryInterface (+ псевдоним FontRegistry) | singleton, заблокирован после прогрева | Прогревается из preload_fonts; после блокировки ни один запрос не может его изменить |
ImageRegistry | singleton (синглтон) | Ограниченный кэш с вытеснением давно не использованных элементов (LRU); размер задаётся через image_cache_mb; не заблокирован |
DocumentFactoryInterface (+ псевдоним DocumentFactory) | singleton (синглтон) | Не хранит состояние; использует два общих реестра |
Psr\Http\Client\ClientInterface | singleton (синглтон) | Клиент с защитой от подделки запросов, обёртка над curl-клиентом; создаётся из tsa.* |
TsaClient | scoped (в пределах области действия) | null, когда tsa.url пуст |
SignerInterface | factory (фабрика) | null, когда подписание отключено или сертификат пуст |
PdfDocumentInterface (+ псевдоним nextpdf) | factory (фабрика) | Новый NextPDF\Core\Document при каждом разрешении, с применёнными метаданными по умолчанию |
EmbedderInterface, ValidatorInterface, ProfileInterface, SchematronRunnerInterface | factory (фабрика) | Разрешаются в конкретные реализации Premium; без nextpdf/premium ошибка возникает при первом разрешении |
Привязка документа применяет defaults.creator, defaults.language и, если значение непустое, defaults.author к каждому новому документу. Когда pdfa не равно null, включается PDF/A (Premium). Когда присутствует секция artisan и существует класс фабрики браузера Chrome, применяется конфигурация отрисовщика Chrome.
Метод has() контейнера принимает один строковый идентификатор (PSR-11 §1.1.2). Контракты электронных счетов привязаны, поэтому has() возвращает для них true, даже когда Premium отсутствует. Если конкретная реализация отсутствует, ошибка возникает только при создании.
Отключение автообнаружения
Заголовок раздела «Отключение автообнаружения»Добавьте пакет в массив dont-discover приложения, затем зарегистрируйте провайдер вручную:
{ "extra": { "laravel": { "dont-discover": ["nextpdf/laravel"] } }}<?php
declare(strict_types=1);
return [ App\Providers\AppServiceProvider::class, NextPDF\Laravel\NextPdfServiceProvider::class,];Порядок разрешения конфигурации
Заголовок раздела «Порядок разрешения конфигурации»Каждый ключ разрешается в таком порядке: переменная окружения → опубликованное значение config/nextpdf.php → значение пакета по умолчанию, объединённое в register(). Большинство ключей принимает либо имя NEXTPDF_*, либо устаревшее имя переменной окружения TCPDF_*. Предпочтительно использовать NEXTPDF_*.
Диагностика
Заголовок раздела «Диагностика»php artisan package:discover --ansiСтрока, в которой указан nextpdf/laravel, подтверждает обнаружение. Поскольку провайдер работает отложенно, сами привязки не появляются до первого разрешения. Именно строка обнаружения служит правильным сигналом об успехе.
Граничные случаи и подводные камни
Заголовок раздела «Граничные случаи и подводные камни»- Публикация конфигурации регистрируется только в консольном контексте, поэтому веб-запрос сам по себе её никогда не запускает. Запускайте
vendor:publishиз интерфейса командной строки (CLI). - Наряду с ключами реестра, фабрики, HTTP-клиента, подписывающего компонента, метки времени и документа
provides()включает четыре ключа контрактов электронных счетов. - После свежей установки может казаться, что пакет ничего не делает до первого подходящего разрешения. Это особенность конструкции отложенного провайдера, а не сбой.
Производительность
Заголовок раздела «Производительность»register() имеет сложность O(1), поскольку создаёт только замыкания. Прогрев реестра шрифтов имеет сложность O(f) по числу предзагруженных шрифтов и выполняется один раз на рабочий процесс. Отложенная регистрация провайдера не включает затраты на создание NextPDF в путь загрузки фреймворка до тех пор, пока привязка действительно не используется.
Замечания по безопасности
Заголовок раздела «Замечания по безопасности»Отложенная конструкция сужает поверхность атаки при загрузке. Заблокированный реестр шрифтов не позволяет одному запросу изменить состояние шрифтов другого запроса в долгоживущих рабочих процессах. Полный обзор угроз см. в /integrations/laravel/security-and-operations/.
Соответствие
Заголовок раздела «Соответствие»| Утверждение | Источник | Пункт | reference_id (идентификатор ссылки) |
|---|---|---|---|
| Последовательные разрешения могут различаться в зависимости от стратегии привязки | PSR-11 Container (контейнер) | §1.1.2 | |
has() принимает один строковый идентификатор | PSR-11 Container (контейнер) | §1.1.2 |
Официальная документация по пакетам Laravel 12 подтверждает имена ключей обнаружения Laravel (https://laravel.com/docs/12.x/packages, получено 2026-05-18).
Коммерческий контекст
Заголовок раздела «Коммерческий контекст»Конкретные реализации Premium разрешаются через те же ключи отложенных привязок. Эта необязательная возможность Enterprise не требует менять код в пакете Core, описанном здесь. См. https://nextpdf.dev/get-license/?intent=laravel-signing.
См. также
Заголовок раздела «См. также»- /integrations/laravel/install/ — установка и публикация
- /integrations/laravel/overview/ — архитектура пакета
- /integrations/laravel/integration/ — пошаговое руководство по полной настройке
- /integrations/laravel/configuration/ — все ключи конфигурации