ข้ามไปยังเนื้อหา

แยกวิเคราะห์และตรวจสอบ PDF เพื่ออ่านข้อเท็จจริงเชิงโครงสร้าง

สูตรนี้ใช้ Core inspector แบบ Quick fallback เพื่ออ่านข้อเท็จจริงเชิงโครงสร้างจากไฟล์ Portable Document Format (PDF) ผลลัพธ์ประกอบด้วยเวอร์ชัน จำนวนหน้า แฟล็กการเข้ารหัสลับ แฟล็กลายเซ็น แฟล็กสิ่งที่แนบ ขนาดไฟล์ และแฟล็กความเสี่ยง Quick ทำงานทั้งหมดภายในกระบวนการเดียว โดยไม่ใช้ Spectrum sidecar และไม่เข้าถึงเครือข่าย ใช้สำหรับการคัดกรองอย่างรวดเร็ว ไม่ใช่ตัวตรวจสอบความถูกต้อง

Terminal window
composer require nextpdf/core:^3

ไฟล์ PDF บันทึกเวอร์ชันไว้ในส่วนหัวของไฟล์ (ISO 32000-2 §7.5.2) ส่วนท้าย (trailer) มีตัวระบุไฟล์ (/ID) เป็นไบต์สตริงสองชุด (ISO 32000-2 §7.5.5) เมื่อมีลายเซ็น ดิกชันนารีลายเซ็นจะจัดเก็บ Cryptographic Message Syntax (CMS) SignedData ที่เข้ารหัสแบบ Distinguished Encoding Rules (DER) ไว้ใน Contents (ISO 32000-2 §12.8.1) Quick fallback ใช้การสแกนไบต์ของเอกสารแบบมีขอบเขตจำกัด เพื่อค้นหาเวอร์ชัน ประมาณจำนวนหน้า และระบุแฟล็กที่แสดงว่ามีการเข้ารหัสลับ ลายเซ็น และสิ่งที่แนบหรือไม่

สร้าง 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',
);

โปรแกรมแบบครบในตัวนี้ทำงานในเฟรมเวิร์กทดสอบของ cookbook และสอดคล้องกับ examples/39-parse-and-inspect-pdf.php: โดยสร้าง PDF ขนาดเล็กแบบหลายหน้าในหน่วยความจำ อ่านข้อเท็จจริงเชิงโครงสร้างด้วย Quick fallback และกำหนดเส้นทางตามข้อเท็จจริงเหล่านั้น ไม่ใช่ตามคำตัดสินด้านความเชื่อถือ เงื่อนไขการกำหนดเส้นทางเป็นเพียงตัวอย่างประกอบ ให้แทนที่ด้วยไปป์ไลน์ คิวตัวตรวจสอบ และการกักกันของคุณเอง

<?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 : 2
Encrypted : no
Signed : no
Attachments : no
File size : <n> bytes
Risk flags : 0
Route: continue (no risks, unsigned, unencrypted)
  • Quick คือการคัดกรอง ไม่ใช่การตรวจสอบความถูกต้อง โดยรายงานสิ่งที่มีอยู่และสิ่งที่ไม่มี Quick ไม่ตรวจสอบลายเซ็น ไม่ถอดรหัสลับเนื้อหา และไม่ยืนยันความสอดคล้องตามข้อกำหนด ให้ถือว่าผลลัพธ์เป็นข้อมูลนำเข้าสำหรับการกำหนดเส้นทาง
  • จำนวนหน้าเป็นค่าประมาณ Quick fallback นับเครื่องหมายระบุอ็อบเจกต์หน้า (page-object markers) กราฟอ็อบเจกต์ที่จงใจสร้างให้ผิดรูปแบบอาจทำให้จำนวนคลาดเคลื่อนได้ ใช้ระดับความลึกที่ Spectrum รองรับเมื่อคุณต้องการจำนวนที่แม่นยำ
  • Standard/Full ต้องใช้ sidecar new InspectConfig() (ระดับความลึก Standard) และ InspectConfig::full() ต้องใช้ Spectrum sidecar ทั้งสองจะโยน INSPECT-SIDECAR-001 เมื่อใช้งานไม่ได้ และจะไม่ลดระดับลงเป็น Quick โดยไม่แจ้งเตือน
  • ข้อมูลนำเข้าว่างเปล่า การส่งสตริงว่างจะโยน inspect exception พร้อมข้อความ “PDF data must not be empty”
  • ขอบเขตของแฟล็กการเข้ารหัสลับ แฟล็กนี้สะท้อนรายการ /Encrypt ในส่วนท้าย (trailer) ไฟล์ที่ถูกตั้งแฟล็กจะไม่ถูกถอดรหัสลับโดย inspector

Quick fallback ใช้การสแกนแบบมีขอบเขตจำกัด ไม่ใช่การแยกวิเคราะห์แบบเต็มรูปแบบ ใช้เพื่อกำหนดเส้นทางไฟล์ขาเข้าจำนวนมากล่วงหน้าก่อนการประมวลผลที่หนักกว่า

inspector ทำงานภายในกระบวนการและอ่านเฉพาะเครื่องหมายเชิงโครงสร้างเท่านั้น ไบต์ของเอกสารจะไม่ออกจากโฮสต์ และไม่มีการดึงข้อความของเอกสารออกมา แฟล็กความเสี่ยง เช่น JavaScript ที่ฝังอยู่ เป็นสัญญาณเพื่อช่วยกำหนดเส้นทาง ไม่ใช่การยืนยันว่าไฟล์นั้นปลอดภัยหรือไม่ปลอดภัย

ข้อความข้อกำหนดข้อรหัสอ้างอิง (reference_id)
ส่วนหัวของไฟล์บันทึกเวอร์ชัน PDFISO 32000-2§7.5.2
ส่วนท้าย (trailer) /ID เป็นตัวระบุไฟล์ที่ประกอบด้วยไบต์สตริงสองชุดISO 32000-2§7.5.5
ดิกชันนารีลายเซ็น Contents เก็บ DER CMS SignedDataISO 32000-2§12.8.1

สูตรนี้รายงานเฉพาะข้อเท็จจริงเชิงโครงสร้างเท่านั้น และไม่ได้ยืนยันว่าไฟล์ถูกต้อง ปลอดภัย หรือสอดคล้องตามข้อกำหนด

การตรวจสอบระดับ Standard และ Full ทำงานผ่าน Spectrum sidecar ทั้งสองเพิ่มการวิเคราะห์อ็อบเจกต์ ฟอนต์ และรูปภาพที่ละเอียดยิ่งขึ้น Quick fallback ที่อธิบายไว้ในที่นี้เป็นส่วนของ Core และทำงานแบบออฟไลน์