Contracts / Документ
Домен документа включает контракты, с помощью которых вы формируете вывод в Portable Document Format (PDF): PdfDocumentInterface для содержимого, DocumentFactoryInterface для безопасного для воркеров создания, контракты реестров шрифтов и изображений, а также три перечисления для доставки и макета. Все они имеют статус stable с 1.0.0 или 1.7.0.
Установка
Заголовок раздела «Установка»composer require nextpdf/core:^3Концептуальный обзор
Заголовок раздела «Концептуальный обзор»PdfDocumentInterface — основная поверхность API. Он определяет управление страницами, выбор шрифта, размещение текста в ячейках и многострочных ячейках, отрисовку Hypertext Markup Language (HTML), встраивание изображений и итоговый вывод. Каждый метод возвращает static, поэтому вы можете объединять вызовы в цепочку. Document::createStandalone() возвращает конкретный экземпляр, соответствующий интерфейсу. Типизируйте свои сервисы этим интерфейсом, чтобы внутренние компоненты движка оставались заменяемыми.
Есть два пути создания документа. В классическом запросе PHP FastCGI Process Manager (PHP-FPM) createStandalone() создает самодостаточный документ с приватными реестрами. Долгоживущие воркеры, включая RoadRunner, Swoole и Laravel Octane, используют другой путь. Там DocumentFactoryInterface::create() возвращает новый одноразовый Document. Документ читает реестры уровня процесса, но никогда их не изменяет. Фабрика держит синглтоны FontRegistryInterface и ImageRegistryInterface. Каждый документ получает собственный контекст отрисовки и писатель. Это изолирует сбои: один документ не может повредить общее состояние, от которого зависит другой документ.
Контракты реестров поддерживают производительность воркеров. FontRegistryInterface разбирает файл шрифта один раз и кэширует разобранные метаданные на время жизни процесса. Вы можете заблокировать реестр после прогрева, чтобы рабочий трафик не мог его изменить. ImageRegistryInterface кэширует декодированные двоичные данные изображений по ограниченной политике вытеснения наименее недавно использованных (LRU). Метаданные изображений остаются в памяти даже после вытеснения двоичных данных. Оба реестра предоставляют memoryUsage() для планирования ёмкости. ImageRegistryInterface расширяет ResettableService, который вытесняет кэшированные данные, не разрушая структурные метаданные. При нехватке памяти воркер может сбросить кэши изображений и продолжать обслуживание.
Домен дополняют три перечисления. OutputDestination выбирает встроенный показ, принудительную загрузку, запись в файловую систему или возврат строки как есть. Orientation выбирает книжную или альбомную ориентацию. Alignment выбирает выравнивание текста по левому краю, по центру, по правому краю или по ширине. Каждое перечисление использует устаревший код TCPDF как своё значение, поэтому мост compat-tcpdf сопоставляет их без коллизий. Обещание обратной совместимости для этих перечислений аддитивно. Ни один вариант не удаляется. Новые варианты могут появиться в минорном выпуске.
Поверхность API
Заголовок раздела «Поверхность API»| Тип | Вид | Ключевые члены | Стабильность | С версии |
|---|---|---|---|---|
PdfDocumentInterface | интерфейс | addPage(), setMargins(), setFont(), cell(), multiCell(), writeHtml(), image(), output(), save() | stable | 1.0.0 |
DocumentFactoryInterface | интерфейс | create(?Config): Document | stable | 1.7.0 |
ResettableService | интерфейс | reset(): void | stable | 1.7.0 |
FontRegistryInterface | интерфейс | register(), get(), warmup(), lock(), isLocked(), registerFromBinary(), memoryUsage() | stable | 1.7.0 |
ImageRegistryInterface | интерфейс | load(), loadFromString(), getMetadata(), memoryUsage() (расширяет ResettableService) | stable | 2.0.0 |
OutputDestination | enum (string) | Inline, Download, File, String | stable | 1.0.0 |
Orientation | enum (string) | Portrait, Landscape | stable | 1.0.0 |
Alignment | enum (string) | Left, Center, Right, Justify | stable | 1.0.0 |
Страница типографики полностью документирует FontRegistryInterface и ImageRegistryInterface. Эта страница описывает их роль в жизненном цикле создания.
Пример кода — быстрый старт
Заголовок раздела «Пример кода — быстрый старт»<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Hello World');$doc->addPage();$doc->setFont('helvetica', '', 24);$doc->cell(0, 15, 'Hello, NextPDF!', newLine: true);$doc->setFont('helvetica', '', 12);$doc->cell(0, 10, 'This is a minimal PDF generated with NextPDF.', newLine: true);$doc->save(__DIR__ . '/output/01-hello-world.pdf');Пример кода — рабочая среда
Заголовок раздела «Пример кода — рабочая среда»<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\PdfFactory;use NextPDF\ValueObjects\{Margin, PageSize};
$factory = PdfFactory::new() ->withPageSize(PageSize::A4()) ->withMargins(new Margin(15.0, 15.0, 15.0, 15.0)) ->withCompress(true) ->withLang('en');
// The same configured factory creates independent documents.$doc = $factory->create();$doc->setTitle('PdfFactory Example');$doc->setAuthor('NextPDF');$doc->addPage();$doc->setFont('helvetica', '', 16);$doc->cell(0, 12, 'Created via PdfFactory', newLine: true);
$doc2 = $factory->create();$doc2->addPage();$doc2->setFont('helvetica', '', 12);$doc2->cell(0, 10, 'Second document from the same factory.');
$doc->save(__DIR__ . '/output/02-pdf-factory.pdf');PdfFactory — неизменяемый строитель. Каждый вызов with*() возвращает новый экземпляр. Внутри он компонует DocumentFactoryInterface, поэтому модель реестров для воркеров из обзора применяется без дополнительной настройки.
Граничные случаи и подводные камни
Заголовок раздела «Граничные случаи и подводные камни»createStandalone()создает приватные реестры. В цикле воркера из-за этого каждый шрифт разбирается заново при каждом запросе. Вместо этого используйтеDocumentFactoryInterfaceс общими реестрами.- Объект
Documentпо конструкции одноразовый. Повторное использование одного экземпляра для разных логических документов приводит к утечке состояния. Вызывайтеcreate()для каждого документа и позвольте сборщику мусора освободить его. FontRegistryInterface::lock()приводит к тому, чтоregister(),addFontDirectory()иwarmup()выбрасываютLogicException. Блокируйте после прогрева, никогда во время обработки запроса.OutputDestination::Fileзаписывает в файловую систему сервера и возвращает байты как есть.save()— это явный путь к файлу. Не смешивайте эти два варианта для одного документа.cell()ради совместимости с TCPDF принимаетbool|stringдля аргумента границы. Пустая строка — это не то же самое, чтоfalse. Передавайте именно то типизированное значение, которое имеете в виду.
Производительность
Заголовок раздела «Производительность»Реестры шрифтов и изображений делают домен документа системой с ограничением по памяти, а не системой уровня отдельного запроса. Основная стоимость приходится на разбор шрифта при первом запросе. performance_budget составляет 1500 мс стенового времени и 64 МБ пикового потребления на три документа в примере с воркером. Почти весь этот бюджет уходит на первый разбор шрифта. После прогрева работа, относимая к контракту, на каждый документ остается O(1): поиск в реестре и выделение контекста. memoryUsage() на любом из реестров возвращает MemoryReport для оперативного планирования ёмкости. ResettableService::reset() ограничивает пиковую память при устойчивой нагрузке.
Замечания по безопасности
Заголовок раздела «Замечания по безопасности»Контракты документа не несут криптографической поверхности, но остаются два эксплуатационных риска. Во-первых, image() принимает путь или единообразный указатель ресурса (URL). Если входные данные недоверенные, ограничивайте удалённую загрузку через ExternalResourcePolicyInterface (см. страницу политики безопасности), а не передавайте напрямую URL, которые контролирует пользователь. Во-вторых, writeHtml() — это точка входа в конвейер HTML. Недоверенная разметка должна пройти через HtmlSecurityPolicyInterface перед отрисовкой. Слой документа сам не выполняет санитизацию. Это задача домена политики безопасности, и, поскольку это контракт, вы можете предоставить более строгую политику без форка.
Соответствие
Заголовок раздела «Соответствие»Контракты документа реализуют структуру документа PDF 2.0, как она определена в ISO 32000-2. Обработка вывода, страниц и шрифтов создает косвенные объекты и поток перекрёстных ссылок согласно ISO 32000-2 §7. Слой писателя выдает содержимое согласно контракту слоя движка и записи об архитектурном решении (ADR-010). Эта страница не заявляет никаких притязаний на уровне пунктов сверх структурного соответствия. Страницы извлечения и доступности документируют соответствие PDF/A и PDF/UA и содержат нормативные таблицы.
См. также
Заголовок раздела «См. также»- Contracts: 41 общедоступный интерфейс (SPI) — обзор интерфейса поставщика услуг (SPI) и уровней стабильности.
- Contracts / Typography — полная документация по
FontRegistryInterface. - Contracts / Security Policy — политики, которые управляют доступом к
writeHtml()иimage(). - Core — конкретные классы
DocumentиPdfFactory. - Document — модуль построения документа.
- Writer — слой, выдающий объекты PDF для этих контрактов.