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

Inspect: интроспекция и предпечатная проверка PDF

Модуль Inspect читает существующий файл формата Portable Document Format (PDF) и выдаёт сведения о его содержимом: оценку сложности, аудит шрифтов и изображений, подсказки по соответствию и флаги рисков. Предпечатная политика превращает отчёт в решение pass/fail, так что вы можете отсеять документ до попадания в конвейер.

Стабильность: экспериментальная. Интроспекция всё ещё развивается. Форма InspectResult, набор флагов рисков и необязательный ускоренный путь инспекции могут меняться между минорными версиями. Используйте модуль для диагностики и отсева; пока не полагайтесь на форму его результата в долгосрочных контрактах.

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

Используйте Inspector как точку входа. Он реализует InspectorInterface и предоставляет один метод: inspect(string $pdfData, InspectConfig $config = new InspectConfig()): InspectResult. Инспектор работает только на чтение: разбирает PDF и характеризует его, но не изменяет документ.

InspectResult — это структурированный отчёт. Он содержит оценку сложности, аудиты, подсказки и набор флагов RiskFlag. Используйте hasRisks() / hasRisk(RiskFlag $flag), чтобы ветвиться по конкретному риску, а не разбирать произвольный текст. ComplexityScore предоставляет числовую оценку и диапазон через category(). FontAuditEntry и ImageAuditEntry описывают встроенные ресурсы. ComplianceHint отмечает вероятные проблемы соответствия. InspectIssue фиксирует конкретную находку. InspectDepth задаёт глубину инспекции, а toSpectrumDepth() сопоставляет эту глубину с ускоренным путём, когда доступен сайдкар Spectrum. Инспекция работает и без сайдкара. Сайдкар меняет только производительность, но не контракт. InspectResponseParser строит InspectResult из исходного ответа (например, ответа ускоренного пути) с необязательным идентификатором трассировки.

PreflightPolicy — это уровень принятия решений. evaluate(InspectResult $result) применяет настроенную политику к результату и возвращает итог политики. Весь модуль помечен @since 2.2.0.

ТипКлючевые членыРоль
Inspectorinspect(string $pdfData, InspectConfig $config): InspectResultИнспектор PDF в режиме только для чтения (@since 2.2.0)
InspectResulthasRisks(), hasRisk(RiskFlag), аксессоры score/auditСтруктурированный отчёт об инспекции (@since 2.2.0)
ComplexityScorecategory()Числовая оценка сложности + диапазон (@since 2.2.0)
FontAuditEntry / ImageAuditEntryаксессоры ресурсовАудит встроенных ресурсов (@since 2.2.0)
ComplianceHint / InspectIssueаксессоры находокПодсказки по соответствию и находки (@since 2.2.0)
InspectDepth (enum)toSpectrumDepth()Глубина инспекции → ускоренный путь (@since 2.2.0)
PreflightPolicyevaluate(InspectResult): array, toArray()Предпечатное решение pass/fail (@since 2.2.0)
InspectResponseParserparse(array, InspectConfig, ?string $traceId): InspectResultСтроит результат из исходного ответа (@since 2.2.0)

Запустите composer docs:generate-api-php -- --module=Inspect, чтобы сгенерировать полную таблицу PHPDoc.

Исходник examples/34-inspect-layout-boxes.php демонстрирует чтение геометрии страницы. Этот пример инспектирует профиль рисков произвольного PDF:

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Inspect\Inspector;
$result = (new Inspector())->inspect(file_get_contents('/srv/in/incoming.pdf'));
if ($result->hasRisks()) {
echo "Complexity: {$result->complexityScore()->category()}; risks present.\n";
}

Передайте входящий PDF через предпечатную политику и отклоните его при любом риске.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Inspect\Inspector;
use NextPDF\Inspect\PreflightPolicy;
use Psr\Log\LoggerInterface;
final readonly class IngestPreflight
{
public function __construct(
private Inspector $inspector,
private PreflightPolicy $policy,
private LoggerInterface $logger,
) {}
public function accept(string $pdfData): bool
{
$result = $this->inspector->inspect($pdfData);
$verdict = $this->policy->evaluate($result);
if ($verdict !== []) {
$this->logger->warning('PDF rejected at preflight.', ['findings' => $verdict]);
return false;
}
return true;
}
}
  • inspect() работает только на чтение. Он никогда не изменяет и не восстанавливает входные данные; не ждите, что он вернёт “исправленный” документ.
  • hasRisk(RiskFlag) — это точная проверка. Если ветвиться только по hasRisks(), каждый риск будет обрабатываться одинаково; обычно вам нужен конкретный флаг.
  • InspectDepth управляет затратами. Глубокая инспекция большого PDF работает значительно медленнее; используйте наименьшую глубину, которая отвечает на ваш вопрос.
  • Ускоренный путь Spectrum меняет производительность, а не контракт результата. Пишите код, опираясь на InspectResult, а не на форму ускоренного ответа.
  • PreflightPolicy::evaluate() возвращает находки; метод не выбрасывает исключение. Пустой результат означает прохождение проверки; действуйте по возвращаемому значению.

Затраты на инспекцию растут с размером документа и выбранной InspectDepth. Поверхностная инспекция выполняется быстро; глубокий аудит большого PDF может приблизиться к бюджету. Если доступен путь Spectrum, он разгружает тяжёлый разбор. performance_budget в 1500 ms по времени / 64 MB по пику описывает эталонную нагрузку. Профиль воспроизводимости — structural: результат может включать идентификатор трассировки и тайминги. Эти поля могут различаться между запусками, тогда как находки остаются стабильными для одних и тех же входных данных.

Inspector::inspect() разбирает недоверенные байты PDF; именно для этого он и нужен, поэтому относитесь к входным данным как к враждебным. Для документов, предоставленных пользователем, запускайте инспекцию в изолированном рабочем процессе и ограничивайте размер входных данных на стороне источника. Намеренно сложный PDF является вектором отказа в обслуживании независимо от глубины. Результат описывает документ, но не очищает его; вердикт “низкий риск” — это эвристика, а не гарантия безопасности. Относитесь к извлечённым строкам и метаданным как к недоверенным. См. модель угроз движка в /modules/core/security/.

Этот модуль сообщает подсказки по соответствию; он не выдаёт авторитетный вердикт о соответствии. ComplianceHint эвристически отмечает вероятные проблемы. Для PDF/A, PDF/UA и International Organization for Standardization (ISO) 32000-2 авторитетный вердикт о соответствии выдают эталонные валидаторы, управляемые /modules/core/cli/, а также оракул и эталонные наборы, описанные в /modules/core/conformance/. Не считайте чистый результат Inspect сертификацией соответствия.