符規驗證:行程內預先檢查搭配外部 oracle
快速概覽
標題為「快速概覽」的區段本範例會先以 NextPDF 的純 PHP、行程內符規驗證器執行快速的結構性預先檢查,再把決定性的符規判定交給獨立驗證器。行程內檢查是必要條件,而非充分條件:通過只是一項結構性事實,不是符規裁決。本範例由 examples/33-validate-conformance.php 及其 tests/Cookbook/Php/ValidateConformanceRecipeTest.php 測試載具支撐。
composer require nextpdf/core:^3行程內驗證器不需要任何外部工具鏈。決定性的 gate 步驟需要在 PATH 上備妥一個外部驗證器。本範例指向 veraPDF。你不需要 Pro 或 Enterprise 套件。
概念總覽
標題為「概念總覽」的區段NextPDF 在 \NextPDF\Compliance\Validator 下提供行程內驗證器。它們會驗證特定的規範性不變量,而不需要啟動任何外部行程:
PdfRValidator— ISO 23504-1(PDF/R-1)§5/§6 的位元組串流檢查:檔案標頭允許清單、generation-0 物件、§6.5.7 頁面內容運算子允許清單(僅限q/Q/cm/Do),以及 §6.4.3 Info 字典鍵允許清單。它會回傳一個扁平的PdfRValidationFinding[];空清單代表每一項受管控的 §6 檢查都通過了。ArlingtonValidator— 以僅回報模式執行 PDF Association 的機器可讀 Arlington 文法:它絕不會作為建置把關,並且會在每一筆 finding 上記下已釘選的文法提交 SHA,讓稽核端能比對到已知的上游快照。
這些檢查的範圍是刻意限縮的。它們能抓出輸出契約與規範之間的偏移,但並不為 PDF/A-4 或 PDF/UA-2 之類的設定檔建立 ISO 符規。那項判定屬於以裁決作為建置 gate 的獨立驗證器(ISO 19005-4 §6.7.3 對 PDF/A 已明確指出這點)。本範例把界線劃得很清楚:它會在行程內執行預先檢查,然後印出並執行負責作出決定的外部 oracle 指令。
下方圖示呈現這道兩階段 gate。它只遵循一條規則:唯有外部 oracle 的裁決可被回報為符規。
API 介面
標題為「API 介面」的區段API 介面由 PHPDoc 產生。以下是主要進入點:
\NextPDF\Compliance\Validator\PdfRValidator::validate(string $pdfBytes): list<PdfRValidationFinding>\NextPDF\Compliance\Validator\PdfRValidationFinding(readonly:clause、severity、message)\NextPDF\Compliance\Validator\ArlingtonValidator::validateReportOnly(string $pdfPath): list<ArlingtonFinding>\NextPDF\Core\Document::output(?string $filename, OutputDestination $dest): string(用OutputDestination::String取得原始位元組)
程式碼範例 — 快速上手
標題為「程式碼範例 — 快速上手」的區段<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Compliance\Validator\PdfRValidator;use NextPDF\Contracts\OutputDestination;use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->addPage();$doc->setFont('helvetica', '', 12);$doc->cell(0, 10, 'Document under conformance review.', newLine: true);
$bytes = $doc->output(dest: OutputDestination::String);
$findings = (new PdfRValidator())->validate($bytes);
// A finding list is a structural fact, not a conformance verdict.echo $findings === [] ? "No in-process PDF/R-1 findings (necessary, not sufficient).\n" : count($findings) . " in-process finding(s); not a conformance verdict.\n";程式碼範例 — 正式環境
標題為「程式碼範例 — 正式環境」的區段在正式環境中,呼叫端會把行程內驗證器當成一道低成本 gate,一旦出現明顯的結構性偏移就快速失敗,接著再執行外部 oracle 作為決定性的符規判定。唯有 oracle 的裁決可被回報為符規。
$bytes = $doc->output(dest: OutputDestination::String);$doc->save($out);
// 1. In-process pre-check — necessary, not sufficient.$findings = (new PdfRValidator())->validate($bytes);foreach ($findings as $finding) { fwrite(STDERR, sprintf("[%s] §%s — %s\n", $finding->severity, $finding->clause, $finding->message));}
// 2. The authoritative gate — the external validator decides.$exitCode = 0;$report = [];exec('verapdf --flavour 4 ' . escapeshellarg($out), $report, $exitCode);
if ($exitCode !== 0) { fwrite(STDERR, "veraPDF FAILED — not reported conforming\n"); fwrite(STDERR, implode("\n", $report) . "\n"); exit(1);}
echo "veraPDF PASS — the validator reports the file conforming\n";用 php examples/33-validate-conformance.php 執行這個範例。它會建置一份一般 PDF,然後印出行程內的 findings。一般 PDF 預期會產生 PDF/R-1 findings,而這個結果正是教學重點。接著本範例會印出決定性的外部 oracle 指令。
邊界情況與陷阱
標題為「邊界情況與陷阱」的區段- 必要而非充分。
PdfRValidator回傳空的 finding 清單,只代表受管控的 §6 檢查通過了,僅此而已。它不是 PDF/A-4 或 PDF/UA-2 的符規主張。絕不可僅憑行程內結果就回報符規。 - 一般 PDF 依設計就會通不過 PDF/R-1。 PDF/R-1 是僅含影像的點陣設定檔;一般文字 PDF 本來就會合理地產生 §6.5.7 與 §6.4.3 findings。本範例刻意示範這點,藉以說明行程內輸出是一項結構性事實,而非裁決。
- Arlington 是僅回報的。
ArlingtonValidator::validateReportOnly()絕不會擲出例外,也絕不會把關。在僅文法模式下,它會發出一筆infofinding,證明已釘選的文法 SHA 已載入;當文法尚未具現化時,它會回傳一個空清單。切勿以它建立 pass/fail gate — 它是一項交叉檢查產物。 - 位元組 vs. 檔案。
PdfRValidator::validate()接收原始位元組字串(OutputDestination::String);外部 oracle 則需要一個檔案路徑。請用save()持久化,供 oracle 步驟使用。 - 空輸入。 把空字串或無標頭字串傳給
PdfRValidator::validate()會回傳一筆§6.2.2錯誤 finding,而不是擲出例外。請檢查 finding 清單;不要預設會有例外。
行程內驗證器會對 PDF 進行單趟正規表示式與位元組掃描。對一般文件而言,它們速度快、配置負擔輕,並維持在 2000 ms / 128 MB 的預算之內。當外部 oracle 存在時,它會主導整體耗時,但它是在行程外執行的。適用於語意可重現性設定檔。本範例的價值在於可觀察的驗證行為,而測試載具會透過結構化 AST 加上中繼資料比對來檢查該行為。
安全性注意事項
標題為「安全性注意事項」的區段資料落地與 PII 緩解
標題為「資料落地與 PII 緩解」的區段驗證器會在行程內讀取文件位元組,不會有任何資料離開該行程。然而,外部 oracle 會收到該檔案。若你執行的是託管驗證器,文件內容就會離開你的邊界。對於敏感內容,請優先採用本機驗證器執行檔,或在驗證前先做去識別化。
安全遙測與日誌清理
標題為「安全遙測與日誌清理」的區段Findings 可能會引用物件路徑與運算子片段。本範例會把 findings 寫到 STDERR,並把一行固定的進度訊息寫到 STDOUT。對於敏感文件,請避免讓 finding 日誌進入共用接收端。絕不可記錄原始的 PDF 位元組。
威脅模型
標題為「威脅模型」的區段乾淨的行程內結果並不是完整性或真確性的訊號。懷有惡意的產生端可以製作一份能通過受限範圍行程內檢查、卻通不過完整驗證器的檔案,或是一份格式正確但具誤導性的檔案。請把行程內通過視為一道快速過濾,絕不可視為信任依據。
FIPS 模式行為
標題為「FIPS 模式行為」的區段本範例不執行任何密碼學運算。FIPS 模式不會改變它的行為。不會發生任何簽章、加密,或對信任素材做摘要的動作。
| 陳述 | 規範 | 條款 | 參考 ID |
|---|---|---|---|
| PDF/R-1 的頁面內容只使用 q/Q/cm/Do 允許清單中的運算子。 | ISO 23504-1 | §6.5.7 | |
| PDF/R-1 的頁面是僅含影像的點陣內容。 | ISO 23504-1 | §6.5.5 | |
| PDF/R-1 會限制文件資訊字典的鍵。 | ISO 23504-1 | §6.4.4 | |
| Arlington 文法是一項機器可讀的物件模型交叉檢查。 | Arlington PDF 模型 | 文法 | |
| 符規由驗證器、而非產生端決定。 | ISO 19005-4 | §6.7.3 |
NextPDF 的行程內驗證器會驗證特定的規範性不變量。**支援不等於符規;驗證不等於認證。**乾淨的行程內結果並不能建立 ISO 符規;那項判定必須由獨立驗證器(例如 veraPDF)作出。請讓它的裁決成為建置 gate。