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

Манифест отрисовки: переносимый запрос на отрисовку

Манифест отрисовки — это переносимое описание того, что отрисовывать: входные данные, шаблон, шрифты, локаль, профиль соответствия, политика подписи, цель вывода и флаг Fast-Web-View. Каждый транспорт собирает и отправляет один и тот же RenderManifest — будь то интерфейс командной строки (CLI), интеграция с фреймворком, API SaaS-приложения или будущий потоковый коннектор. Контракт детерминирован: два равных манифеста сериализуются в байт-идентичное представление JavaScript Object Notation (JSON), и каждый манифест содержит производный ключ идемпотентности, чтобы системы ниже по цепочке могли распознать и дедуплицировать одну и ту же отрисовку.

Манифест — это контракт Core. Он определяет схему; движок и обработчик потока Premium выполняют запрос.

Окно терминала
composer require nextpdf/core:^3

Используйте построитель как стабильный способ создания или RenderManifest::fromArray() для десериализованного манифеста. Прямой конструктор помечен как @internal: новые необязательные поля добавляются со значениями по умолчанию, поэтому построитель и fromArray() принимают их, не ломая ваши места вызова.

examples/manifest/build.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Manifest\OutputObjectKey;
use NextPDF\Manifest\RenderManifestBuilder;
use NextPDF\Manifest\TemplateRef;
$manifest = RenderManifestBuilder::create('invoice-2026-0001')
->withInlineInput('<h1>Invoice 2026-0001</h1>')
->withTemplate(TemplateRef::html())
->withOutputKey(OutputObjectKey::file('invoices', '2026-0001.pdf'))
->withLocale('en-US')
->linearized()
->build();
// Deterministic, canonical-key-order JSON — equal manifests are byte-identical.
$json = $manifest->toJson();
ПолеЗначение
jobIdСтабильный для вызывающей стороны логический идентификатор, который отражается в событиях и квитанциях. Исключён из ключа идемпотентности.
idempotencyKeyДетерминированный ключ дедупликации (см. ниже).
inputИсточник данных для отрисовки: встроенная полезная нагрузка, унифицированный идентификатор ресурса (URI) или ссылка на набор данных вместе с хешем содержимого.
templateИнтерфейс отрисовки и необязательный идентификатор шаблона.
fontsОбъявленный набор шрифтов (по умолчанию пустой).
localeЯзыковой тег BCP-47 (по умолчанию en-US).
conformanceProfileСтабильный идентификатор профиля (по умолчанию none).
signaturePolicyСтабильный идентификатор политики (по умолчанию none).
targetКлюч выходного объекта, формат и политика перезаписи.
linearizeФлаг Fast-Web-View; сочетается с линеаризацией.
metadataНепрозрачная скалярная карта key/value, которая отражается в событиях.

IdempotencyKey::derive() хеширует только подмножество манифеста, определяющее отрисовку: шаблон, хеш содержимого входных данных, шрифты, локаль, профиль соответствия, политику подписи, флаг linearize и ключ цели. Он намеренно исключает jobId и metadata, поэтому два запроса с одинаковыми входными данными, определяющими отрисовку, включая цель вывода, получают один ключ и могут быть дедуплицированы, даже если их идентификаторы задания или метаданные отслеживания различаются. Вызывающая сторона также может предоставить явный ключ; isDerived() сообщает, каким путём он был получен.

RenderManifest::SCHEMA_VERSION фиксирует версию схемы (в настоящее время 1.0). В пределах мажорной версии эволюция происходит только за счёт добавлений: читающая сторона допускает неизвестные ключи из более новой минорной схемы, но отклоняет более новую мажорную версию. SchemaCompatibility::assertReadable() обеспечивает это в fromArray(), а canRead() / isForwardRead() позволяют проверить совместимость без исключений.

Поскольку манифест — это объект передачи данных (DTO) readonly, конструктор которого помечен как @internal, создавайте его через построитель или fromArray(). Новые поля добавляются как параметры конструктора со значениями по умолчанию, поэтому добавление поля не ломает эти места вызова.

RenderManifestValidator::validate() не выбрасывает исключения и собирает все проблемы: он возвращает каждую найденную проблему, а не останавливается на первой. Он отклоняет небезопасные ключи вывода (обход каталогов, абсолютные пути, обёртки потоков), более одного источника входных данных, неизвестный идентификатор профиля соответствия, недопустимую локаль BCP-47 и несоответствие политики перезаписи. warnings() возвращает рекомендательные неблокирующие примечания.

use NextPDF\Manifest\RenderManifestValidator;
$problems = (new RenderManifestValidator())->validate($manifest);
if ($problems !== []) {
// Each entry is a stable, human-readable problem string.
}

SingleDocumentRenderer детерминированно превращает один манифест в один файл формата Portable Document Format (PDF). Это чистый компонент: он возвращает байты и их дайджест sha-256, но не записывает файл, поэтому промежуточное размещение и фиксация ровно один раз остаются на стороне вызывающего кода (или обработчика потока).

use NextPDF\Manifest\Render\SingleDocumentRenderer;
use NextPDF\Manifest\Render\StandaloneDocumentFactory;
$renderer = new SingleDocumentRenderer(new StandaloneDocumentFactory());
$outcome = $renderer->render($manifest);
$bytes = $outcome->bytes;
$digest = $outcome->sha256;
$pages = $outcome->pageCount;
ТипВидКлючевые членыСтабильностьС версии
RenderManifestreadonly DTOtoArray(), toJson(), fromArray(), canonicalDigestInput(), SCHEMA_VERSIONстабильный3.2.0
RenderManifestBuilderпостроительcreate(), with*(), linearized(), build()стабильный3.2.0
IdempotencyKeyобъект-значениеof(), derive(), equals(), isDerived()стабильный3.2.0
SchemaCompatibilityвспомогательный классcanRead(), isForwardRead(), assertReadable()стабильный3.2.0
RenderManifestValidatorсервисvalidate(), warnings()стабильный3.2.0
SingleDocumentRendererсервисrender(): RenderOutcomeстабильный3.2.0

fromArray() выбрасывает RenderManifestException, когда обязательное поле отсутствует или версия схемы нечитаема.