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

Устранение неполадок в пакете NextPDF для Laravel

На этой странице каждый наблюдаемый сбой пакета сопоставлен с проверенной первопричиной на уровне исходного кода. В каждой записи указаны симптом, причина и способ устранения.

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

Большинство сообщений о проблемах относится к пяти группам: обнаружение, разрешение зависимостей в контейнере, подпись, задания очереди и имена файлов в ответах по протоколу передачи гипертекста (HTTP). По замыслу пакет сообщает об ошибках явно. Ненастроенные необязательные возможности возвращают null, а небезопасный ввод вызывает типизированные исключения. Обычно симптом прямо указывает на причину.

СимптомПроверенная причинаРешение
После установки поставщик не регистрируетсяВ приложении отключено обнаружение через extra.laravel.dont-discoverУдалите пакет из dont-discover или зарегистрируйте NextPdfServiceProvider вручную в bootstrap/providers.php
config('nextpdf') пустКонфигурация не была объединена, потому что ни одна из заявленных привязок не была разрешена (отложенный поставщик)Разрешите любую запись provides() или подтвердите обнаружение командой php artisan package:discover --ansi
config/nextpdf.php не создан командой публикацииНесовпадение тега публикацииИспользуйте точный тег: php artisan vendor:publish --tag=nextpdf-config
RuntimeException: “NextPDF requires the ext-mbstring/ext-zlib PHP extension” (требуется расширение PHP)Необходимое расширение PHP отсутствует во время выполненияУстановите или включите mbstring и zlib в php.ini
СимптомПроверенная причинаРешение
app(SignerInterface::class) возвращает nullПодпись отключена или сертификат пуст в nextpdf.signatureЗадайте signature.enabled = true и действительный signature.certificate; установите nextpdf/premium, чтобы подключить конкретную реализацию средства подписи
app(TsaClient::class) возвращает nullnextpdf.tsa.url пустНастройте tsa.url (и при необходимости credentials/pins)
Класс типа версии PDF/A не найденnextpdf.pdfa имеет значение не null, но nextpdf/premium не установленУстановите nextpdf/premium или верните pdfa в значение null
Класс не найден при разрешении контракта электронного счётаПривязки зарегистрированы, но конкретные реализации Premium отсутствуютУстановите nextpdf/premium; контракты электронных счётов разрешаются отложенно, и без Premium ошибка возникает только при первом разрешении
Один и тот же документ изменён в двух логических операцияхПривязка документа работает как фабрика; вы повторно использовали один разрешённый экземплярРазрешайте новый PdfDocumentInterface для каждого документа

Контейнер без записи выбрасывает исключение “не найдено” при вызове get() (PHP Standard Recommendation 11 (PSR-11) §1.1.2). Контракты электронных счётов привязаны, поэтому has() контейнера возвращает true. Ошибка возникает из-за отсутствующей конкретной реализации Premium на этапе создания объекта, а не из-за самого контейнера.

СимптомПроверенная причинаРешение
InvalidArgumentException: Path traversal sequences are not allowedВыходной путь содержит сегмент ..Используйте абсолютный путь без обхода каталогов внутри своего каталога хранилища
InvalidArgumentException: Stream wrappers are not allowedВ пути используется схема, например php://Используйте обычный путь в файловой системе
InvalidArgumentException: Output path contains null bytesПуть содержит нулевой байт \0Очистите путь перед отправкой задания
InvalidArgumentException: Output path must end with .pdf extensionПуть не заканчивается на .pdf (без учёта регистра)Используйте суффикс .pdf (или .PDF)
Задание выполняется, но файл пуст или неверенЗамыкание-построитель не вернуло настроенный документВерните документ из построителя; задание сохраняет возвращённое значение
Задание использует неверную очередь или тайм-аутnextpdf.queue.* задан не так, как ожидалосьЗадайте queue.queue, queue.connection и queue.timeout; для tries и backoff нужен подкласс

Проверки пути выполняются внутри handle() на воркере, поэтому недопустимый путь приводит к ошибке во время выполнения, а не при отправке задания. Это сделано намеренно: воркер проверяет сериализованную полезную нагрузку очереди там, где он её потребляет.

СимптомПроверенная причинаРешение
Неожиданно имя загружаемого файла равно document.pdf (значение по умолчанию)Вы передали пустое имя файла; фабрика использует значение по умолчаниюПередайте непустое имя файла
В имени файла пропали путь или специальные символыСредство очистки имён файлов удаляет разделители пути, управляющие символы и нулевые байтыПередавайте только базовое имя файла; это ожидаемое усиление защиты
Имя файла с символами вне ASCII отображается в некоторых клиентах как кракозябрыОтвет выдаёт filename*= согласно Request for Comments 5987 (RFC 5987) для имён с символами вне ASCII; старые клиенты читают резервное имя в ASCIIОжидаемо; укажите безопасное для ASCII имя, если для устаревшего клиента требуется точное совпадение
Потоковый ответ не содержит Content-LengthПотоковые ответы по замыслу не содержат Content-Length (вывод по частям)Ожидаемо; используйте непотоковые inline()/download(), если требуется заголовок длины
Окно терминала
# Confirm the provider is discovered
php artisan package:discover --ansi
# Inspect merged configuration
php artisan tinker --execute="dump(config('nextpdf.queue'));"
resource: src/Laravel/NextPdfServiceProvider.php (null-check pattern)
<?php
declare(strict_types=1);
use NextPDF\Contracts\SignerInterface;
$signer = app(SignerInterface::class);
if ($signer === null) {
// Signing not configured, or nextpdf/premium not installed.
// Continue without a signature, or fail with a clear message.
}
  • При отложенном поставщике свежая установка может выглядеть “сломанной” до первого подходящего разрешения. Считайте наличие пакета в списке package:discover признаком успеха.
  • Если image_cache_mb = null, пакет использует резервное значение 50 МБ; только 0 отключает кэш. Сообщение “кэш не отключается” обычно означает, что использовали null.
  • Если signature.level = null, пакет неявно использует резервный уровень PDF Advanced Electronic Signatures (PAdES) B-B. Сообщение о “неожиданном B-B” обычно означает, что уровень оставили незаданным.

Если первые запросы на долгоживущем воркере выполняются медленно, реестр шрифтов разбирается по требованию. Заполните nextpdf.preload_fonts, чтобы прогрев выполнялся один раз при загрузке воркера. Подробности см. в /integrations/laravel/configuration/ и /integrations/laravel/boot-and-discovery/.

Отклонение путей и имён файлов — меры безопасности, а не ошибки. Не обходите их, выполняя предварительное декодирование или ослабляя проверки. Вместо этого направляйте вывод файлов через контролируемый путь хранилища. См. /integrations/laravel/security-and-operations/.

УтверждениеИсточникПунктreference_id (идентификатор ссылки)
Отсутствующая запись контейнера приводит к ошибке “не найдено” при вызове get()PSR-11 Container (контейнер)§1.1.2
  • /integrations/laravel/install/ — шаги обнаружения и публикации
  • /integrations/laravel/configuration/ — каждый ключ и его значение по умолчанию
  • /integrations/laravel/production-usage/ — внедрение зависимостей (DI) и шаблоны очередей
  • /integrations/laravel/security-and-operations/ — зачем нужны проверки путей