跳转到内容

Inspect:PDF 自省与预检

Inspect 模块会读取已有 PDF,并报告其中包含的内容:复杂度分数、字体与图像审计、一致性提示以及风险标志。预检策略会把这份报告转化为 pass/fail 决策,让你能在文档进入流水线之前先行把关。

稳定性:实验性。 自省接口仍在演进。因此, InspectResult 的结构、风险标志集合以及可选的加速检测路径,都可能在次要版本之间变化。请将它用于诊断与把关;目前还不适合把长期契约绑定在其结果结构上。

Terminal window
composer require nextpdf/core:^3

Inspector 是入口点。它实现 InspectorInterface,并且只对外提供一个方法:inspect(string $pdfData, InspectConfig $config = new InspectConfig()): InspectResult。它是只读的——会解析一份 PDF 并描述其特征,但不会修改该文档。

InspectResult 是结构化报告。它承载复杂度分数、审计信息、提示以及一组 RiskFlag。它提供 hasRisks() / hasRisk(RiskFlag $flag),让调用方可以针对特定风险进行分支,而不必解析自由文本。ComplexityScore 会提供一个数值分数,以及一个 category() 级别。FontAuditEntryImageAuditEntry 描述内嵌资源。ComplianceHint 会标示可能的一致性问题。InspectIssue 会记录一项具体的查核结果。InspectDepth 决定检测深入到什么程度,而 toSpectrumDepth() 会在 Spectrum sidecar 可用时将其映射到加速路径。即使没有 sidecar,检测仍可运行。sidecar 只会改变性能,不会改变契约。InspectResponseParser 会从原始响应(例如加速路径响应)构建一个 InspectResult,并可选择附带一组 trace id。

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): arraytoArray()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 路径可用时,会分担繁重的解析工作。1500 ms 墙钟时间 / 64 MB 峰值的 performance_budget 是参考工作负载。可复现性配置为 structural:结果可以携带一组 trace id 与计时信息。两次运行在这些字段上会有所不同;但对于相同输入,查核结果是稳定的。

Inspector::inspect() 会解析不受信任的 PDF 字节——这正是它的全部用途,因此请把输入视为恶意内容。对于用户提供的文档,请在受限的工作进程中运行检测,并在上游约束输入大小。蓄意复杂化的 PDF 无论检测深度如何,都是拒绝服务攻击向量。该结果只是描述文档,不会对其进行净化——“低风险”判定只是一种启发式结论,并非安全保证。请将抽取出的字符串与元数据视为不受信任的内容。请参阅 /modules/core/security/ 中的引擎威胁模型。

本模块报告的是一致性提示;并非权威的一致性判定。ComplianceHint 会以启发式方式标示可能的问题。权威的 PDF/A、PDF/UA 与 ISO 32000-2 一致性判定,以 /modules/core/cli/ 驱动的参考验证器,以及 /modules/core/conformance/ 中所述的预言机与黄金套件为准。请勿把一份干净的 Inspect 结果当作一致性认证。