Контракты / Извлечение
Область извлечения определяет контракты, с помощью которых вы читаете и проверяете файлы Portable Document Format (PDF), а также преобразуете их содержимое в структурированные данные. Она включает инспектор, валидаторы соответствия, менеджер PDF/A, контракты для импортированных объектов, контракты эмбеддингов и векторного индекса, а также подпространство имён валидатора электронных счетов.
Установка
Заголовок раздела «Установка»composer require nextpdf/core:^3Концептуальный обзор
Заголовок раздела «Концептуальный обзор»InspectorInterface читает необработанные байты PDF и возвращает структурированный InspectResult. Результат содержит перечень объектов в файле. Используйте этот контракт для любого инструмента, который читает PDF, созданный вне этого движка.
ExternalComplianceValidatorInterface связывает движок с внешним инструментом проверки, например veraPDF. Этот инструмент проверяет PDF/A и PDF/Universal Accessibility (PDF/UA). Если инструмент проверки не настроен, нулевая реализация возвращает результат “недоступно”. Сайт без veraPDF всё равно работает. ProfileValidatorInterface сверяет среду выполнения с профилем развёртывания, включая обязательные и рекомендуемые расширения. Он возвращает типизированный вердикт.
PdfAManagerInterface поддерживает соответствие файла PDF/A спецификации, пока писатель формирует файл. Он блокирует JavaScript, действия форм на JavaScript и встроенное шифрование. PDF/A запрещает все три механизма. Он также проверяет, что каждый шрифт внедрён, задаёт метаданные, соответствующие спецификации, и записывает необходимые объекты перед каталогом. Реальный класс поставляется в редакции Pro. Ядро находит его через class_exists() и приводит к типу контракта. В движке с открытым исходным кодом нет платных зависимостей.
Для импортированных объектов есть два контракта: ImportedFormObjectInterface и EmbeddedPdfObjectInterface. Они предоставляют типизированный доступ к объектам, прочитанным из существующего PDF, чтобы движок мог внедрить их повторно. Путь без потерь сохраняет необработанные байты словаря. Резервный путь предоставляет разобранный массив словаря для объектов, взятых из потоков объектов. Каждый повторно внедрённый объект является косвенным объектом PDF. Его идентифицируют номер объекта и номер поколения, как определено в ISO 32000-2 §7.3.10.
Контракты эмбеддингов поддерживают поиск. EmbeddingServiceInterface преобразует текст в плотный вектор и сообщает размерность и имя модели, чтобы вызывающий код мог адаптироваться во время выполнения. Редакция Pro выполняет модель на центральном процессоре (CPU). Редакция Enterprise выполняет модель на графическом процессоре (GPU). VectorIndexInterface строит индекс ближайших соседей и выполняет поиск по нему. Это небольшой внутрипроцессный индекс для использования в ядре. Поиск большего масштаба остаётся в контракте, доступном только в редакции Enterprise.
Группа EInvoice содержит межуровневый инструмент проверки электронных счетов. ValidatorInterface выполняет предварительные проверки полезной нагрузки Cross Industry Invoice (CII) или Universal Business Language (UBL). SchematronRunnerInterface выполняет проход по бизнес-правилам. ValidationResult фиксирует находки и нарушения правил. Инструмент проверки должен отклонять некорректный ввод, возвращая результат, а не выбрасывая исключение. Он также должен защищать от полезных нагрузок с объявлением типа документа (DOCTYPE) и чрезмерно больших полезных нагрузок.
Поверхность API
Заголовок раздела «Поверхность API»| Тип | Вид | Ключевые члены | Стабильность | С версии |
|---|---|---|---|---|
InspectorInterface | интерфейс | inspect(string, InspectConfig): InspectResult | экспериментальный | 2.2.0 |
ExternalComplianceValidatorInterface | интерфейс | validate(string, ComplianceFlavour), isAvailable() | экспериментальный | 2.4.0 |
ProfileValidatorInterface | интерфейс | validate(DeploymentProfile): DeploymentProfileResult | экспериментальный | 2.4.0 |
PdfAManagerInterface | интерфейс | validateNoJavaScript(), validateFont(), validateNoEncryption(), applyOutputProfile(), writeRequiredObjects() | стабильный | 1.10.0 |
ImportedFormObjectInterface | интерфейс | getWidth(), getHeight(), getEmbeddedObjects(), getResourcesDict(), getMediaBox(), getContentStream() | стабильный | 1.8.0 |
EmbeddedPdfObjectInterface | интерфейс | getRawDictionaryBytes(), getRawStreamData(), getDictionary() | стабильный | 1.8.0 |
EmbeddingServiceInterface | интерфейс | embed(), batchEmbed(), getDimension(), getModelName() | экспериментальный | 2.1.0 |
VectorIndexInterface | интерфейс | build(), search(), delete(), count() | экспериментальный | 2.1.0 |
EInvoice\ValidatorInterface | интерфейс | validate(string, ValidatorContext): ValidationResult | экспериментальный | 5.1.0 |
EInvoice\ValidationResult | финальный класс readonly | $isValid, getErrors(), getWarnings(), fail() | экспериментальный | 5.1.0 |
Пространство имён EInvoice также публикует SchematronRunnerInterface, ProfileInterface, ValidationFinding, RuleViolation и перечисления ProfileType, RuleSeverity и ValidationFindingLevel.
Пример кода — Быстрый старт
Заголовок раздела «Пример кода — Быстрый старт»<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\InspectorInterface;use NextPDF\Inspect\InspectConfig;
/** * Inspect a PDF and report its object count. * * @param InspectorInterface $inspector A configured inspector. * @param string $pdfData Raw PDF bytes. */function describe(InspectorInterface $inspector, string $pdfData): \NextPDF\Inspect\InspectResult{ return $inspector->inspect($pdfData, new InspectConfig());}Эта функция зависит от контракта, поэтому ей подходит любая реализация инспектора.
Пример кода — Продакшен
Заголовок раздела «Пример кода — Продакшен»<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\EInvoice\ValidatorInterface;use NextPDF\Contracts\EInvoice\ValidatorContext;use NextPDF\Contracts\ExternalComplianceValidatorInterface;use NextPDF\ValueObjects\ComplianceFlavour;use Psr\Log\LoggerInterface;
final readonly class InvoiceConformanceService{ public function __construct( private ValidatorInterface $invoiceValidator, private ExternalComplianceValidatorInterface $pdfaValidator, private LoggerInterface $logger, ) {}
/** * Validate the invoice XML, then the PDF/A-3 carrier. * * @param string $xml The CII or UBL invoice payload. * @param string $pdfPath Absolute path to the PDF/A-3 carrier. */ public function validate(string $xml, string $pdfPath, ValidatorContext $ctx): bool { $result = $this->invoiceValidator->validate($xml, $ctx);
if (!$result->isValid) { $this->logger->warning('Invoice XML invalid', [ 'errors' => \count($result->getErrors()), ]);
return false; }
if (!$this->pdfaValidator->isAvailable()) { $this->logger->info('PDF/A validator unavailable; skipping carrier check.');
return true; }
$carrier = $this->pdfaValidator->validate($pdfPath, ComplianceFlavour::PdfA3b);
return $carrier->isConformant(); }}Этот сервис явно обрабатывает недоступный валидатор, а не предполагает, что валидатор всегда присутствует.
Граничные случаи и подводные камни
Заголовок раздела «Граничные случаи и подводные камни»EInvoice\ValidatorInterface::validate()возвращает неуспешныйValidationResultдля некорректного ввода. Он не выбрасывает исключение при нарушениях корректности. Проверяйте$isValid; не оборачивайте вызов в try/catch для этого случая.ExternalComplianceValidatorInterface::isAvailable()необходимо проверить, прежде чем полагаться на вердикт. Нулевая реализация возвращает “недоступно”. Если трактовать это как “несоответствующий”, появятся ложноотрицательные результаты.EmbeddedPdfObjectInterface::getRawDictionaryBytes()возвращаетnullдля объектов, взятых из потока объектов. Используйте резервный вариантgetDictionary(). Не предполагайте, что необработанные байты существуют.EmbeddingServiceInterface::getDimension()различается по уровню редакции. Код, который выделяет вектор фиксированной ширины, должен читать размерность во время выполнения, а не задавать её жёстко.VectorIndexInterface::build()требует списков векторов и идентификаторов одинаковой длины с согласованными размерностями. Несоответствие вызываетInvalidArgumentException. Проверяйте списки, прежде чем строить индекс.
Производительность
Заголовок раздела «Производительность»Стоимость проверки и валидации растёт с размером документа и количеством объектов. performance_budget в 1500 ms по времени выполнения и 64 MB по пику покрывает один документ умеренного размера. Внешний вызов veraPDF добавляет время выполнения отдельного процесса. Это время находится вне бюджета движка, и вызов следует выносить из пути запроса. Стоимость эмбеддинга растёт с длиной текста; пакетная обработка гораздо дешевле цикла, особенно на модели GPU. Предпочитайте batchEmbed(). Векторный поиск сублинеен по размеру индекса для внутрипроцессного индекса. Профиль воспроизводимости — structural. Отчёт о валидации фиксирует метку времени и отпечаток среды. Из-за этих полей два запуска различаются, тогда как вердикт о соответствии остаётся идентичным.
Заметки по безопасности
Заголовок раздела «Заметки по безопасности»Извлечение читает документы, созданные не этим движком, поэтому любой ввод считается недоверенным. И инспектор, и валидатор электронных счетов разбирают байты, предоставленные извне. Валидатор электронных счетов должен блокировать полезные нагрузки с объявлением типа документа (DOCTYPE), чрезмерно большие полезные нагрузки и полезные нагрузки с запрещёнными управляющими символами до разбора, чтобы предотвратить атаки через внешние сущности Extensible Markup Language (XML) и атаки billion-laughs. Повторное внедрение импортированных объектов копирует байты из стороннего PDF. Вредоносный исходный объект может нести враждебное содержимое, поэтому повторное внедрение сохраняет байты и не выполняет их. Принудительное применение PDF/A удаляет JavaScript и действия. Менеджер PDF/A отклоняет JavaScript и шифрование, поскольку оба запрещены профилем и оба являются векторами злоупотребления в долгоживущем архивном документе. Относитесь к проверяемому содержимому, импортированным объектам и XML счёта как к враждебному вводу на всём протяжении.
Соответствие
Заголовок раздела «Соответствие»| Утверждение | Стандарт | Пункт | Подтверждение |
|---|---|---|---|
| PDF/A-4 запрещает JavaScript и действия форм на JavaScript; менеджер PDF/A отклоняет оба. | ISO 19005-4 | §6.7.1 | процитировано по пункту (нет в корпусе) |
| Каждый повторно внедрённый объект является косвенным объектом PDF, идентифицируемым номером объекта и поколением. | ISO 32000-2 | §7.3.10 |
ISO 19005-4 цитируется по пункту. Его нет в корпусе проверяемых цитат, поэтому reference_id не записывается. Утверждение о косвенном объекте по ISO 32000-2 закреплено в глоссарии. Оба утверждения приведены в пересказе. Движок не воспроизводит нормативный текст.
Коммерческий контекст
Заголовок раздела «Коммерческий контекст»Ядро определяет и фиксирует контракты извлечения. Продакшен-код за PdfAManagerInterface, EmbeddingServiceInterface и VectorIndexInterface поставляется в редакциях Pro и Enterprise, включая модели эмбеддинга на CPU и GPU и полный путь принудительного применения PDF/A. Ядро разрешает их во время выполнения через class_exists(). Поэтому движок с открытым исходным кодом не несёт коммерческих зависимостей, а API не меняется при обновлении.
См. также
Заголовок раздела «См. также»- Контракты: 41 публичный интерфейс — обзор интерфейса поставщика услуг (SPI) и уровни стабильности.
- Контракты / Документ — контракты документа, которые формируют носитель PDF/A.
- Контракты / Подписание — подписанное архивирование, которое сочетается с принудительным применением PDF/A.
- Инспектирование — реализация инспектора, стоящая за
InspectorInterface. - Текст — извлечение текста, которое использует проверенные объекты.
- Метаданные — метаданные PDF/A, настраиваемые менеджером.