剖析並檢視 PDF 的結構性事實
這則 recipe(範例)會透過 Core 檢視器的 Quick 後備機制,從 PDF 讀取結構性事實。這些事實包含版本、頁數、加密旗標、簽章旗標、附件旗標、檔案大小,以及風險旗標。Quick 全程在行程內執行,不需要 Spectrum sidecar,也不會連網。請將它用於快速初步分流,而不是當作驗證器。
composer require nextpdf/core:^3概念總覽
標題為「概念總覽」的區段PDF 會在檔頭記錄版本(ISO 32000-2 §7.5.2)。trailer 會包含一個由兩個 byte 字串組成的檔案識別碼(/ID)(ISO 32000-2 §7.5.5)。若有簽章,該簽章會以簽章字典表示,其 Contents 存放 DER 編碼的 CMS SignedData(ISO 32000-2 §12.8.1)。Quick 後備機制會透過對文件位元組進行有界掃描,推導出版本、頁數估計值,以及加密、簽章與附件是否存在的旗標。
API 介面
標題為「API 介面」的區段先呼叫 new Inspector(),再呼叫 ->inspect(string $pdfData, InspectConfig::quick())。結果會是一個 InspectResult,包含 $pdfVersion、$pageCount、$isEncrypted、$hasSigned、$hasAttachments、$fileSizeBytes、$riskFlags,以及 hasRisks() 輔助方法。
程式碼範例 — 快速上手
標題為「程式碼範例 — 快速上手」的區段<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Inspect\InspectConfig;use NextPDF\Inspect\Inspector;
$pdf = file_get_contents(__DIR__ . '/document.pdf');$result = (new Inspector())->inspect($pdf, InspectConfig::quick());
printf( "v%s, %d page(s), encrypted=%s, signed=%s\n", $result->pdfVersion ?? '?', $result->pageCount, $result->isEncrypted ? 'yes' : 'no', $result->hasSigned ? 'yes' : 'no',);程式碼範例 — 正式環境
標題為「程式碼範例 — 正式環境」的區段這是一支可獨立執行,並可在 harness 中執行的程式。它對應 範例 examples/39-parse-and-inspect-pdf.php:會在記憶體中建立一份小型多頁 PDF,用 Quick 後備機制讀取它的結構性事實,再根據這些事實進行路由(而非根據信任判定)。這段路由分支只是示意用途。請接上你自己的 pipeline、驗證器佇列與隔離區。
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;use NextPDF\Inspect\InspectConfig;use NextPDF\Inspect\Inspector;
// A self-contained input so the program runs with no external file.$doc = Document::createStandalone();$doc->setTitle('Parse-and-inspect demo');$doc->setAuthor('NextPDF Cookbook');$doc->addPage();$doc->setFont('helvetica', '', 12);$doc->cell(0, 10, 'Page one of the parse-and-inspect demonstration.', newLine: true);$doc->addPage();$doc->cell(0, 10, 'Page two.', newLine: true);$pdf = $doc->getPdfData();
$result = (new Inspector())->inspect($pdf, InspectConfig::quick());
echo 'PDF version : ' . ($result->pdfVersion ?? 'unknown') . "\n";echo 'Pages : ' . $result->pageCount . "\n";echo 'Encrypted : ' . ($result->isEncrypted ? 'yes' : 'no') . "\n";echo 'Signed : ' . ($result->hasSigned ? 'yes' : 'no') . "\n";echo 'Attachments : ' . ($result->hasAttachments ? 'yes' : 'no') . "\n";echo 'File size : ' . $result->fileSizeBytes . " bytes\n";echo 'Risk flags : ' . ($result->hasRisks() ? count($result->riskFlags) : 0) . "\n";
// Route on structural facts, not trust verdicts. Replace these calls with// your own pipeline / verifier queue / quarantine.if ($result->isEncrypted) { // $pipeline->decryptThenContinue($pdf); echo "Route: decrypt-then-continue\n";} elseif ($result->hasSigned) { // $verifierQueue->enqueue($pdf); // see the signature-inspect recipe echo "Route: enqueue for cryptographic verification\n";} elseif ($result->hasRisks()) { // $quarantine->hold($pdf, $result->riskFlags); echo "Route: quarantine (risk flags present)\n";} else { // $pipeline->continue($pdf); echo "Route: continue (no risks, unsigned, unencrypted)\n";}
// The harness sets NEXTPDF_COOKBOOK_OUTPUT and runs this script under the// semantic profile; emit the document to the side-channel.$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');file_put_contents($out !== false && $out !== '' ? $out : __DIR__ . '/inspected.pdf', $pdf);以下是預期的 STDOUT(版本與大小取決於建置;這份示範 PDF 未加密、未簽章,也沒有風險):
PDF version : <version>Pages : 2Encrypted : noSigned : noAttachments : noFile size : <n> bytesRisk flags : 0Route: continue (no risks, unsigned, unencrypted)邊界情況與陷阱
標題為「邊界情況與陷阱」的區段- Quick 是初步分流,而非驗證。 它只回報哪些項目存在、哪些項目缺席。它不會驗證簽章、不會解密內容,也不會判定是否符合規範。請將結果作為路由輸入。
- 頁數是估計值。 Quick 後備機制計算的是頁面物件標記的數量。刻意構造的畸形物件圖可能讓這個數字失準。需要精確頁數時,請改用由 Spectrum 支援的檢視深度。
- Standard/Full 需要 sidecar。
new InspectConfig()(深度Standard)與InspectConfig::full()都需要 Spectrum sidecar。當 sidecar 無法使用時,它們會丟出INSPECT-SIDECAR-001,而且不會默默降級為 Quick。 - 空輸入。 空字串會丟出 inspect 例外,錯誤訊息為「PDF data must not be empty」。
- 加密旗標的範圍。 這個旗標反映 trailer 中是否有
/Encrypt項目。被標記的檔案並不會被檢視器解密。
Quick 後備機制是一次有界掃描,而非完整剖析。它適合在較重處理之前,對大量傳入檔案進行高流量前置路由。
安全性備註
標題為「安全性備註」的區段檢視器在行程內執行,而且只會讀取結構性標記。沒有任何文件位元組會離開主機,也不會擷取任何文件文字。風險旗標(例如內嵌的 JavaScript)是供路由參考的建議性訊號。它並不表示該檔案安全或不安全。
符合性
標題為「符合性」的區段| 陳述 | 規範 | 條款 | 參考 ID |
|---|---|---|---|
| 檔頭會記錄 PDF 版本。 | ISO 32000-2 | §7.5.2 | |
trailer 的 /ID 是一個由兩個 byte 字串組成的檔案識別碼。 | ISO 32000-2 | §7.5.5 | |
簽章字典的 Contents 存放 DER 編碼的 CMS SignedData。 | ISO 32000-2 | §12.8.1 |
這則 recipe 回報的是結構性事實,並不斷言該檔案有效、安全或符合規範。
商業情境
標題為「商業情境」的區段Standard 與 Full 檢視深度是透過 Spectrum sidecar 執行的。這些深度會加入更豐富的物件、字型與影像分析。這裡記載的 Quick 後備機制屬於 Core,而且可離線執行。