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

Соответствие: маршрутизация ConformanceMode и граница валидации

NextPDF\Conformance — единственный дискриминатор, который сообщает модулю записи, на какой контракт International Organization for Standardization (ISO) ориентирован файл Portable Document Format (PDF). Библиотека выводит структуры, определённые этим контрактом. Она не сертифицирует — и не может сертифицировать — итоговый файл как соответствующий. Подтвердить соответствие может только внешний валидатор.

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

Модуль Conformance предоставляет два публичных типа. ConformanceMode — типизированное перечисление (backed enum), которое называет целевой контракт (Plain, PdfUa1, PdfUa2, PdfA2, PdfA3, PdfA3b, PdfA3u, PdfA4, PdfA4e, PdfA4f). ConformancePolicy — неизменяемый объект-значение, который объединяет режим с независимыми переключателями строгости.

Режим — единственный источник истины для нижестоящих проверок модуля записи. До появления этого перечисления движок определял, размечен ли документ по спецификации, по набору разрозненных флагов. ConformanceMode::isTagged(), isAccessibility(), isArchival(), pdfaPart(), pdfaConformanceLetter() и requiresPdf17() возвращают типизированный ответ, который модуль записи читает напрямую. Каталог, /MarkInfo, происхождение из заголовка файла и маркеры pdfaid в Extensible Metadata Platform (XMP) остаются согласованными с заявленным намерением.

Воспринимайте границу поддержки буквально. NextPDF Core выводит структуры, которые определяют эти стандарты. ISO 19005-4:2020 §6.7.3 задаёт схему идентификации, фиксирующую, какой вариант PDF/A заявляет файл. ISO 19005-4:2020 устанавливает: соответствие определяют по нормативным требованиям, как описано в разделе 5; делает это средство проверки, а не библиотека, создающая файл. ISO 14289-2:2024 §6 трактует соответствие как свойство, которому удовлетворяет файл. Установка режима NextPDF — необходимое входное условие для соответствующего файла. Сама по себе она не является результатом проверки соответствия.

Здесь действует та же дисциплина “проверено против заявлено”, что и в матрице поддержки Cascading Style Sheets (CSS). Возможность считается проверенной только тогда, когда для неё есть и пройденный тест или прогон оракула, и процитированный пункт стандарта. Всё остальное — это то, что библиотека выводит: полезно, но не гарантирует соответствие. Соответствие относится к итоговому файлу и валидатору, а не к обещанию библиотеки. Проверяйте результат с помощью veraPDF (см. раздел “Соответствие” ниже).

Для архивной работы важна ещё одна граница. Создание PDF/A-4, включая словарь OutputIntent, встроенный профиль International Color Consortium (ICC) и схему расширения XMP, поставляется в расширении nextpdf/pro, а не в Core. В установке, где есть только Core, Document::enablePdfA() выбрасывает InvalidConfigException, потому что возможность security.pdfa не зарегистрирована. Core по-прежнему отвечает за дискриминатор ConformanceMode, поэтому интроспекция и размеченный путь PDF/Universal Accessibility (PDF/UA-2) работают, но сам Core не создаёт файл PDF/A-4.

ТипВидКлючевые члены
NextPDF\Conformance\ConformanceModeenum: stringPlain, PdfUa1, PdfUa2, PdfA2, PdfA3, PdfA3b, PdfA3u, PdfA4, PdfA4e, PdfA4f; isTagged(), isAccessibility(), isArchival(), requiresPdfUa2PageTabs(), pdfaPart(): ?int, pdfaConformanceLetter(): string, requiresPdf17(): bool
NextPDF\Conformance\ConformancePolicyfinal readonly class__construct(ConformanceMode $mode = PdfUa2, bool $strictUa2 = false, bool $rejectUnvalidatedLang = false, …); lax(), strictUa2(), withUax9IsolateSupport(), withoutAstShadowMode(), withBlackPointCompensation(), withStrictOcspProducedAtTolerance(), withAllowStaleOcsp()

ConformancePolicy поддерживает один инвариант в своём конструкторе: строгие переключатели PDF/UA-2 применяются только тогда, когда режим — PdfUa2, а strictUa2 = true принудительно устанавливает rejectUnvalidatedLang = true. Несогласованные комбинации выбрасывают InvalidConfigException вместо тихой деградации.

<?php
declare(strict_types=1);
use NextPDF\Conformance\ConformanceMode;
$mode = ConformanceMode::PdfA4f;
// Introspect the declared contract — these drive writer-side gates.
$mode->pdfaPart(); // 4
$mode->pdfaConformanceLetter(); // 'F'
$mode->requiresPdf17(); // false (PDF/A-4 is PDF 2.0 lineage)
$mode->isArchival(); // true

Путь, поставляемый с Core и задействующий контракт соответствия от начала до конца, — это размеченный маршрут PDF/UA-2. Этот исполняемый пример — examples/31-pdfua2-tagged.php. Он также служит целью оракула для строгого профиля PDF/UA-2.

<?php
declare(strict_types=1);
use NextPDF\Core\Document;
$doc = Document::createStandalone();
// Set the tagged-PDF contract BEFORE writing content so the HTML pipeline
// wires the TaggedContentEmitter at parser-construction time.
$doc->enableTaggedPdf(lang: 'en');
$doc->setTitle('Accessible report');
// … write content …
$doc->save(__DIR__ . '/out/report-ua2.pdf');
// The library has now emitted PDF/UA-2 structures. It has NOT asserted
// conformance. Verify the file with the pinned veraPDF oracle:
//
// php oracle/run.php pdfua.strict
//
// (Requires the veraPDF Docker image — opt-in; see "Conformance" below.)
  • Создание PDF/A-4 доступно в Premium. В установке, где есть только Core, Document::enablePdfA() выбрасывает InvalidConfigException (security.pdfa недоступно). Core отвечает за дискриминатор, но не за вывод OutputIntent/ICC/XMP. См. /specifications/pdfa4/.
  • Зонтичный случай и варианты. PdfA4 — это зонтичный случай, и он возвращает пустой pdfaConformanceLetter(). ISO 19005-4:2020 §6.7.3 требует, чтобы файл, не соответствующий ни PDF/A-4e, ни PDF/A-4f, не содержал pdfa:conformance. Используйте PdfA4e / PdfA4f только для вариантов Annex B / Annex A.
  • Строгий режим PDF/UA-2 включается явно. ConformancePolicy::lax() — это значение по умолчанию, сохраняющее обратную совместимость. strictUa2() принудительно устанавливает /MarkInfo /Marked true и отклоняет языковые теги, не соответствующие Best Current Practice (BCP) 47. Включение его в режиме, отличном от PdfUa2, приводит к исключению.
  • isTagged() учитывает вариант. Plain, PdfA2, PdfA3b и PdfA4e возвращают неразмеченное состояние. Модуль записи не должен выводить дерево структуры только из-за архивного режима.
  • Принятый режим — ещё не проверенный файл. Установка PdfA4 не делает результат корректным файлом PDF/A-4. Запустите валидатор.

ConformanceMode и ConformancePolicy — чистые типы-значения. Разрешение варианта перечисления и диспетчеризация match выполняются за O(1) без выделений памяти помимо неизменяемого объекта политики. Они не добавляют измеримых затрат в процессе записи. Основную часть бюджета модуля занимает модуль записи, а не дискриминатор (wall_ms: 1500). Оракул veraPDF — это внешний шаг непрерывной интеграции (CI), а не часть генерации документа.

Строгие переключатели в ConformancePolicy управляют поведением безопасности с закрытым отказом (fail-closed): securityPkiRfc5280Strict (проверка пути по Request for Comments (RFC) 5280 §6), strictOcspProducedAtTolerance (окно расхождения времени по RFC 6960 §4.2.2.1) и allowStaleOcsp (по умолчанию false; отклонять ответы Open Certification Status Protocol (OCSP), в которых отсутствует nextUpdate). Эти значения по умолчанию консервативны и станут строгими в будущем мажорном выпуске согласно задокументированной стратегии обратной совместимости. Подробнее о пути подписи см. в модуле безопасности и в модели угроз проекта.

NextPDF не сертифицирует соответствие. Он выводит структуры, определённые стандартами ниже. Соответствует ли файл, определяет отдельный валидатор.

СтандартРазделЧто делает NextPDF CoreСтатус
ISO 14289-2:2024 (PDF/UA-2)§6Выводит дерево структуры, /MarkInfo /Marked true (строгий режим), /Lang, XMP pdfuaid через размеченный путь CoreПроверенный профиль: pdfua.strict, проверяется оракулом veraPDF (php oracle/run.php pdfua.strict), когда присутствует исполняемый файл veraPDF (явно включаемый барьер)
ISO 19005-4:2020 (PDF/A-4, формат архивирования)§6.7.3Выводит дискриминатор pdfaid:part / pdfa:conformance через ConformanceModeЗаявлено (вывод дискриминатора, покрыт модульными тестами); создание файла PDF/A-4 доступно только в Premium
ISO 32000-2:2020 (PDF 2.0)§7.5.2Базовая структура catalog/documentЗаявлено (базовое поведение движка)

Поддержка — это не соответствие. NextPDF Core выводит идентификационные структуры PDF/UA-2 и PDF/A-4, а доказательства реализации находятся в tests/Unit/Conformance/. Только валидатор, выполняющий соответствующий профиль, может утверждать, что файл соответствует PDF/A-4 или PDF/UA-2. Согласно разделу 5 ISO 19005-4:2020 определение соответствия — задача валидатора, а не библиотеки, создающей файл.

Барьер veraPDF явно сообщает, что ему требуется. Оракул (oracle/run.php, oracle/lib/OracleRunner.php) вызывает закреплённый образ Docker с veraPDF. Если Docker или образ отсутствует, средство запуска завершается с кодом 2 (сбой инфраструктуры) и ничего не проверяет. Поэтому профиль pdfua.strict — это барьер соответствия, включаемый явно. Он подтверждает соответствие только на машинах, где присутствует исполняемый файл veraPDF. NextPDF не поставляет встроенного валидатора и не делает заявлений о соответствии в его отсутствие.

Цитаты пересказаны из корпуса соответствия NextPDF. Полные 64-символьные дайджесты reference_id записаны во frontmatter страницы и в _normative-evidence-conf.md.