Перейти к содержимому

Загрузка NextPDF в Laravel и автообнаружение

Laravel автоматически обнаруживает NextPdfServiceProvider из composer.json пакета. Провайдер регистрирует отложенные привязки контейнера и публикует файл конфигурации в консольном контексте. На этой странице объясняется, как работает обнаружение и как долго живёт каждая привязка.

Окно терминала
composer require nextpdf/laravel
php artisan vendor:publish --tag=nextpdf-config

Пакет объявляет провайдер и псевдоним фасада в блоке extra.laravel собственного composer.json:

resource: composer.json (extra.laravel)
{
"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().

  1. register() объединяет конфигурацию пакета под ключом nextpdf. Затем он привязывает записи контейнера: реестр шрифтов, реестр изображений, фабрику документов, клиент Hypertext Transfer Protocol (HTTP) по PHP Standards Recommendation 18 (PSR-18), клиент меток времени, подписывающий компонент, документ и контракты электронных счетов. Каждая привязка — это замыкание, поэтому здесь не создаётся ничего ресурсоёмкого.
  2. boot() проверяет, что расширения PHP mbstring и 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; после блокировки ни один запрос не может его изменить
ImageRegistrysingleton (синглтон)Ограниченный кэш с вытеснением давно не использованных элементов (LRU); размер задаётся через image_cache_mb; не заблокирован
DocumentFactoryInterface (+ псевдоним DocumentFactory)singleton (синглтон)Не хранит состояние; использует два общих реестра
Psr\Http\Client\ClientInterfacesingleton (синглтон)Клиент с защитой от подделки запросов, обёртка над curl-клиентом; создаётся из tsa.*
TsaClientscoped (в пределах области действия)null, когда tsa.url пуст
SignerInterfacefactory (фабрика)null, когда подписание отключено или сертификат пуст
PdfDocumentInterface (+ псевдоним nextpdf)factory (фабрика)Новый NextPDF\Core\Document при каждом разрешении, с применёнными метаданными по умолчанию
EmbedderInterface, ValidatorInterface, ProfileInterface, SchematronRunnerInterfacefactory (фабрика)Разрешаются в конкретные реализации 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 приложения, затем зарегистрируйте провайдер вручную:

resource: application composer.json
{
"extra": {
"laravel": {
"dont-discover": ["nextpdf/laravel"]
}
}
}
resource: bootstrap/providers.php
<?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/ — все ключи конфигурации