Пакет Artisan решает две связанные задачи: отрисовывает HTML (Hypertext Markup Language) через Chrome и импортирует получившуюся страницу PDF (Portable Document Format) в документ NextPDF. При отладке разделяйте границы Chrome, парсера и импортёра.
Используйте это руководство при разработке интеграций рендерера, долгоживущих воркеров, диагностики парсера или тестов для nextpdf/artisan.
Слой Владелец Ответственность Не размещать здесь Приложение Приложение Авторизация генерации HTML и выбор конфигурации рендерера. Управление процессом браузера. Политика HTML Приложение и пакет Отклонение небезопасного или слишком большого HTML до отрисовки. Авторизация арендатора или решения бизнес-логики. Рендерер Chrome nextpdf/artisanОтрисовка HTML в отдельный PDF, который создаёт Chrome. Универсальное восстановление PDF или произвольное редактирование PDF. Парсер/импортёр nextpdf/artisanРазбор отрисованного PDF и импорт одной страницы как form XObject. Полная проверка соответствия PDF. Ядро движка nextpdf/nextpdfРазмещение импортированных объектов формы и запись итогового документа. Жизненный цикл CDP (Chrome DevTools Protocol).
Этап Поведение Действие разработчика Создание конфигурации ChromeRendererConfig задаёт исполняемый файл, тайм-аут, поведение CSS (Cascading Style Sheets), размер ввода и режим песочницы.Используйте конфигурацию для конкретного окружения вместо жёстко заданных предположений о среде выполнения. Создание рендерера ChromeHtmlRenderer владеет BrowserPool.Переиспользуйте рендерер внутри воркера, затем закрывайте его при завершении работы. Проверка HTML Политика безопасности проверяет размер и оборачивает документ в CSS по умолчанию. Проверяйте авторизацию вызывающей стороны до этого этапа. Печать через Chrome CDP отрисовывает отдельный PDF. Оставляйте внешние ресурсы заблокированными, если только проверенная политика их не разрешает. Разбор PDF PdfReader::parse() читает данные xref, страницы, объекты, ресурсы и ревизии.Рассматривайте сбои парсера как сбои отрисовки, если диагностика не является целью. Импорт страницы PageImporter::import() извлекает содержимое страницы, media box, ресурсы и встроенные объекты.Импортируйте страницу 0, если только рабочий процесс намеренно не выбирает другую страницу.
Путь Назначение app/Pdf/Renderers/*Обёртка приложения вокруг ChromeHtmlRenderer. app/Pdf/Templates/*Отрисовка HTML-шаблонов и сопоставление DTO (data transfer object) с представлением. app/Pdf/Policies/*Политика отрисовки по размеру HTML, ресурсам и арендатору. tests/Pdf/Renderer/*Дымовые тесты рендерера с небольшими HTML-фикстурами. tests/Pdf/Parser/*Фикстуры парсера для импортированного вывода Chrome.
Держите отрисовку шаблонов отдельно от отрисовки в браузере. Передавайте рендереру готовый HTML и известную ширину страницы.
use NextPDF\Artisan\ ChromeHtmlRenderer ;
use NextPDF\Artisan\ ChromeRendererConfig ;
use NextPDF\Artisan\ PageImporter ;
use NextPDF\Parser\ PdfReader ;
$renderer = new ChromeHtmlRenderer ( new ChromeRendererConfig (
$result = $renderer -> render ( $html , widthPt: 595.28 );
$reader = new PdfReader ($ result -> getPdfData ());
$form = ( new PageImporter ()) -> import ( $reader );
Создавайте один рендерер для процесса-воркера или области видимости запроса. Переиспользуйте его, чтобы не тратить ресурсы на повторный запуск Chrome. Закрывайте его явно, чтобы предотвратить утечки процессов при завершении работы воркера.
final class InvoiceChromeRenderer
public function __construct (
private readonly ChromeHtmlRenderer $renderer ,
public function renderInvoice ( string $html ) : string
-> render ( $html , widthPt: 595.28 )
public function close () : void
$this-> renderer -> close ();
Используйте программные интерфейсы (API) парсера, когда вывод Chrome не удаётся импортировать. Держите диагностику в режиме только чтения и не меняйте состояние парсера после успешного импорта.
Диагностический вопрос Какой API использовать Ожидаемый сигнал Разбирается ли файл? PdfReader::parse()Выбрасывает исключение при недопустимой структуре PDF. Существует ли страница 0? PdfReader::getPage(0)Возвращает PdfObject. Есть ли содержимое? PdfReader::getPageContentStream($page)Непустой поток содержимого. Присутствуют ли ресурсы? PdfReader::getPageResources($page)Массив словаря ресурсов. Есть ли инкрементальные ревизии? PdfReader::getRevisionCount()Счётчик больше единицы. Какой объект дал сбой? PdfTokenizer::getOffset() и контекст исключения парсера.Байтовое смещение для минимизации фикстуры.
Точка расширения Для чего использовать Ограничение ChromeRendererConfig::fromArray()Сопоставление конфигурации фреймворка. Неизвестные или неверно типизированные необязательные значения заменяются значениями по умолчанию. HtmlSecurityPolicyInterfaceПолитика HTML на уровне парсинга. Не заменяет средства контроля транспорта, процессов или авторизации. LoggerInterfaceДиагностика отрисовки и браузера. По умолчанию не записывайте содержимое HTML в журнал. BrowserPoolПереиспользование долгоживущего процесса Chrome. Нужно закрывать при завершении работы воркера. PageImporterВстраивание разобранной внешней страницы. Сначала reader нужно разобрать. Классы парсера Диагностика и импортированный вывод Chrome. Не универсальный набор инструментов для восстановления PDF.
Воспроизведите фрагмент HTML в минимальном тесте отрисовки.
Проверьте maxHtmlSize, CSS по умолчанию и путь к исполняемому файлу Chrome.
Отрисуйте с фиксированной шириной в пунктах.
Разберите возвращённые байты PDF с помощью PdfReader::parse().
Импортируйте страницу 0, если только рабочий процесс намеренно не выбирает другую страницу.
Добавьте тесты на фикстурах для минимального HTML, который воспроизводит каждый сбой.
Закрывайте рендерер в обработчиках завершения работы воркера.
Сбой Где это должно обрабатываться Рекомендуемая реакция Отсутствует исполняемый файл Chrome Проверка развёртывания и путь создания рендерера. Помечайте систему как неготовую до приёма трафика отрисовки. Слишком большой HTML Политика HTML. Отклоняйте до запуска Chrome. Тайм-аут браузера Граница рендерера. Прерывайте отрисовку и записывайте имя шаблона, размер, ширину и тайм-аут. Сбой парсера Граница импорта. Сохраняйте небольшую очищенную фикстуру для отладки, когда это разрешено политикой. Утечка процесса браузера Жизненный цикл воркера. Закрывайте при завершении работы и перезапускайте после контролируемого числа отрисовок.
Аспект По умолчанию Когда переопределять Тайм-аут отрисовки 30 секунд.Увеличивайте только для измеренных документов ограниченного размера. Максимальный размер HTML 5,000,000 байт.Снижайте для публичных конечных точек. Песочница Включена. Отключайте только, когда этого требуют ограничения контейнера и хост изолирован. Высота Авто при heightPt <= 0. Используйте фиксированную высоту для строгих контрактов макета. Внешние ресурсы Заблокированы политикой рендерера. Разрешайте только через проверенную политику ресурсов.
Тесты отрисовки покрывают репрезентативные HTML и CSS.
Тесты безопасности покрывают слишком большой HTML и попытки обращения к заблокированным ресурсам.
Тесты импорта проверяют, что возвращённый объект формы содержит содержимое, media box и ресурсы.
Тесты парсера покрывают таблицу перекрёстных ссылок (xref), поток xref, поток объектов и случаи некорректных фикстур.
Тесты воркера вызывают close() и проверяют, что не осталось процесса браузера.
Тесты производительности фиксируют время отрисовки по шаблону и размеру содержимого.