ตรวจสอบกล่องเค้าโครงก่อนวางเนื้อหา
ภาพรวมโดยย่อ
หัวข้อที่มีชื่อว่า “ภาพรวมโดยย่อ”อ่านเรขาคณิตเค้าโครงปัจจุบันของเอกสารก่อนวางเนื้อหา สูตรนี้อ่านกล่องหน้า ระยะขอบ พื้นที่ห้ามเขียน และตำแหน่งเคอร์เซอร์ปัจจุบัน จากนั้นตรรกะการวางตำแหน่งจะใช้ตัวเลขจริงแทนการคาดเดาพิกัดได้ สูตรนี้มี examples/34-inspect-layout-boxes.php และเฟรมเวิร์กทดสอบ tests/Cookbook/Php/InspectLayoutBoxesRecipeTest.php รองรับ
การติดตั้ง
หัวข้อที่มีชื่อว่า “การติดตั้ง”composer require nextpdf/core:^3ไม่จำเป็นต้องใช้แพ็กเกจ Pro หรือ Enterprise พื้นผิวสำหรับสอบถามเค้าโครงเป็นส่วนหนึ่งของ Core และทำงานบน PHP 8.1 ถึง 8.4
ภาพรวมเชิงแนวคิด
หัวข้อที่มีชื่อว่า “ภาพรวมเชิงแนวคิด”หน้าของ Portable Document Format (PDF) มีกล่องขอบเขต อย่างน้อยต้องมี MediaBox ซึ่งเป็นสี่เหลี่ยมผืนผ้าที่กำหนดขอบเขตของหน้า (ISO 32000-2 §7.7.3.3) เนื้อหาจะถูกวางตำแหน่งในพื้นที่ผู้ใช้ โดยค่าเริ่มต้น พื้นที่ผู้ใช้เริ่มที่มุมล่างซ้าย และหนึ่งหน่วยเท่ากับ 1/72 นิ้ว (§8.3.2) NextPDF ให้มุมมองจากมุมบนซ้ายที่เป็นมิตรต่อผู้เขียน และเปิดเผยเรขาคณิตผ่านเมธอดการสอบถามแบบอ่านอย่างเดียว:
getPageWidth()/getPageHeight()— ขนาดของกล่องหน้าgetMargins()— value object ของMarginที่ใช้งานอยู่ (บน/ขวา/ล่าง/ซ้าย)getPageRegions()— โซนห้ามเขียนที่ประกาศไว้ (PageRegion[]) แต่ละโซนคือสี่เหลี่ยมผืนผ้าที่ไม่เปลี่ยนแปลงได้และห้ามวางเนื้อหาgetX()/getY()— ตำแหน่งเคอร์เซอร์ปัจจุบันในพื้นที่ผู้เขียน
เมธอดเหล่านี้เป็นการอ่านแบบ idempotent คือไม่ปล่อยเนื้อหา ไม่เลื่อนเคอร์เซอร์ และไม่เปลี่ยนสถานะ ใช้เพื่อคำนวณพื้นที่แนวตั้งที่เหลือ จากนั้นตัดสินใจว่าจะเขียนต่อหรือเรียก addPage() คุณยังสามารถจัดวางบล็อกโดยอ้างอิงพื้นที่ห้ามเขียนแทนการใช้ค่าออฟเซ็ตที่ฮาร์ดโค้ดไว้ได้
พื้นผิว API
หัวข้อที่มีชื่อว่า “พื้นผิว API”พื้นผิว application programming interface (API) สร้างขึ้นจาก PHPDoc จุดเข้าใช้งานหลักอยู่ในเทรต \NextPDF\Core\Concerns\HasPages และ HasLayout:
Document::getPageWidth(): float/Document::getPageHeight(): floatDocument::getMargins(): \NextPDF\ValueObjects\MarginDocument::getPageRegions(): array(list<\NextPDF\Layout\PageRegion>)Document::addPageRegion(float $x, float $y, float $w, float $h): staticDocument::getX(): float/Document::getY(): float
ตัวอย่างโค้ด — เริ่มต้นใช้งานอย่างรวดเร็ว
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — เริ่มต้นใช้งานอย่างรวดเร็ว”<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->addPage();
$pageHeight = $doc->getPageHeight();$margins = $doc->getMargins();$cursorY = $doc->getY();
// Vertical space left before the bottom margin.$remaining = $pageHeight - $margins->bottom - $cursorY;
// Geometry is in user-space units (PDF points; 1 pt = 1/72 in).echo sprintf("Page height: %.2f pt\n", $pageHeight);echo sprintf("Bottom margin: %.2f pt\n", $margins->bottom);echo sprintf("Cursor Y: %.2f pt\n", $cursorY);echo sprintf("Remaining: %.2f pt\n", $remaining);ตัวอย่างโค้ด — ระดับการใช้งานจริง
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — ระดับการใช้งานจริง”โปรแกรมแบบครบในตัวนี้ทำงานภายใต้เฟรมเวิร์กทดสอบ และตรงกับ examples/34-inspect-layout-boxes.php โปรแกรมนี้อ่านเรขาคณิตของหน้า ประกาศพื้นที่ห้ามเขียนสำหรับส่วนท้าย และตัดสินใจจากข้อมูลสำหรับแต่ละบล็อก หากบล็อกถัดไปจะชนพื้นที่ห้ามเขียนหรือเลยระยะขอบล่าง โปรแกรมจะเพิ่มหน้าใหม่แทนการพิมพ์ทับ
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Layout Box Inspection Demo');$doc->setLanguage('en');$doc->addPage();
// Read the geometry (idempotent, no side effects). Values are in// user-space units (PDF points; 1 pt = 1/72 in).$pageWidth = $doc->getPageWidth();$pageHeight = $doc->getPageHeight();$margins = $doc->getMargins();
echo sprintf("Page box: %.2f x %.2f pt\n", $pageWidth, $pageHeight);echo sprintf("Cursor start: (%.2f, %.2f)\n", $doc->getX(), $doc->getY());
// A 15 pt tall footer no-write zone across the text column.$footerHeight = 15.0;$footerTop = $pageHeight - $margins->bottom - $footerHeight;$doc->addPageRegion( $margins->left, $footerTop, $pageWidth - $margins->left - $margins->right, $footerHeight,);
$blocks = [ 'Section 1. Each block measures the live cursor against the page box ' . 'and any no-write region before it is placed.', 'Section 2. The lowest Y at which any region starts is the hard floor ' . 'for new content; crossing it forces a page break.', 'Section 3. Reading geometry is idempotent — the query methods never ' . 'advance the cursor, so they are safe in the placement loop.', 'Section 4. This final block forces a second page when the column is ' . 'already near the footer keep-out zone.',];
$blockHeight = 42.0;$pagesUsed = 1;
foreach ($blocks as $index => $text) { $cursorY = $doc->getY();
// Lowest Y a region starts at — the hard floor for new content. $regionFloor = $pageHeight - $margins->bottom; foreach ($doc->getPageRegions() as $region) { $regionFloor = min($regionFloor, $region->y); }
if ($cursorY + $blockHeight > $regionFloor) { $doc->addPage(); ++$pagesUsed; // A fresh page resets the region set; re-declare the footer zone. $footerTop = $doc->getPageHeight() - $doc->getMargins()->bottom - $footerHeight; $doc->addPageRegion( $doc->getMargins()->left, $footerTop, $doc->getPageWidth() - $doc->getMargins()->left - $doc->getMargins()->right, $footerHeight, ); }
$doc->setFont('helvetica', 'B', 12); $doc->cell(0, 8, 'Block ' . ($index + 1), newLine: true); $doc->setFont('helvetica', '', 11); $doc->multiCell(0, 7, $text); $doc->ln(6);}
// The harness sets NEXTPDF_COOKBOOK_OUTPUT and runs this script under the// semantic profile (validated by structural AST + metadata, not a byte hash).$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');$doc->save($out !== false && $out !== '' ? $out : __DIR__ . '/inspect-layout-boxes.pdf');
echo sprintf("Pages used: %d (page breaks decided from layout geometry)\n", $pagesUsed);เอาต์พุตมาตรฐานที่คาดหวัง (STDOUT) ตัวเลขกล่องหน้าสะท้อนขนาดหน้าเริ่มต้น A4 และเคอร์เซอร์เริ่มต้นที่จุดกำเนิดของเนื้อหามุมบนซ้าย:
Page box: 595.28 x 841.89 ptCursor start: (<x>, <y>)Pages used: 2 (page breaks decided from layout geometry)กรณีขอบและข้อควรระวัง
หัวข้อที่มีชื่อว่า “กรณีขอบและข้อควรระวัง”- อ่านก่อนที่หน้าจะมีอยู่
getPageWidth()และgetPageHeight()สะท้อนหน้าปัจจุบัน จึงควรเรียกหลังaddPage()หากเรียกก่อนมีหน้าแรก เมธอดเหล่านี้จะคืนค่าเรขาคณิตของขนาดหน้าเริ่มต้น ไม่ใช่หน้าที่ยังไม่ได้เพิ่ม - พื้นที่เป็นสี่เหลี่ยมผืนผ้าในพื้นที่ผู้เขียน
PageRegionyคือระยะในพื้นที่ผู้เขียนจากมุมบนซ้าย ซึ่งสอดคล้องกับgetY()อย่าปะปนระยะนี้กับพิกัด PDF มุมล่างซ้ายแบบดิบ - การอ่านไม่มีผลข้างเคียง ไม่มีเมธอดการสอบถามใดเลื่อนเคอร์เซอร์หรือปล่อยเนื้อหา การเรียกเมธอดเหล่านี้ในลูปที่กระชับนั้นปลอดภัยและมีค่าใช้จ่ายต่ำ
- ระยะขอบเปลี่ยนได้ในแต่ละหน้า หากหน้าถัดมากำหนดระยะขอบต่างออกไป ให้อ่าน
getMargins()ใหม่แทนการแคชค่าแรกไว้ - พื้นที่ไม่จัดเรียงข้อความใหม่โดยอัตโนมัติ พื้นที่ห้ามเขียนเป็นข้อจำกัดที่คุณต้องปฏิบัติตาม ไม่ใช่ขอบเขตการตัดบรรทัดข้อความอัตโนมัติ สูตรนี้แสดงการตรวจสอบการชนอย่างชัดเจน สำหรับการเขียนแบบกำหนดตำแหน่งอิสระ เอนจินจะไม่ย้ายเนื้อหาออกจากพื้นที่ด้วยตัวเอง
ประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ประสิทธิภาพ”เมธอดทั้งหมดในส่วนนี้เป็นการอ่านพร็อพเพอร์ตี ทำงานในเวลาคงที่ ไม่จัดสรรหน่วยความจำ และไม่มีอินพุตหรือเอาต์พุต ตัวอย่างสร้างเอกสารหลายหน้าขนาดเล็กที่อยู่ภายในงบประมาณ 1500 ms / 96 MB ได้อย่างเหลือเฟือ โปรไฟล์ความสามารถในการทำซ้ำได้เป็นแบบเชิงความหมาย เพราะ PDF ที่สร้างขึ้นมี trailer /ID และเมทาดาทาของการสร้าง การตัดสินใจด้านเรขาคณิตที่สังเกตได้ในตัวอย่างเป็นส่วนสำคัญที่สุด ดังนั้นเฟรมเวิร์กทดสอบจึงตรวจสอบการตัดสินใจเหล่านั้นผ่านการเปรียบเทียบ abstract syntax tree (AST) เชิงโครงสร้างร่วมกับเมทาดาทา แทนการใช้ byte hash
หมายเหตุด้านความปลอดภัย
หัวข้อที่มีชื่อว่า “หมายเหตุด้านความปลอดภัย”- ถิ่นที่อยู่ของข้อมูลและการลดความเสี่ยง PII ไม่เกี่ยวข้อง สูตรนี้อ่านเรขาคณิตและจัดวางข้อความที่ผู้เรียกจัดเตรียมมา จึงไม่เปิดเส้นทางข้อมูลใหม่ ใช้หลักการลดข้อมูลให้น้อยที่สุดกับข้อความที่คุณวางเช่นเดียวกับส่วนอื่น
- เทเลเมทรีที่ปลอดภัยและการชำระล้างบันทึก ตัวอย่างพิมพ์ตัวเลขเรขาคณิตและบรรทัดแสดงความคืบหน้าแบบตายตัว โดยไม่บันทึกข้อความของเอกสาร
- แบบจำลองภัยคุกคาม ไม่เกี่ยวข้อง พื้นผิวการสอบถามเป็นแบบอ่านอย่างเดียวและไม่แยกวิเคราะห์อินพุตภายนอก พื้นผิวนี้ไม่ใช่ขอบเขตความเชื่อถือ
- พฤติกรรมในโหมด FIPS ไม่เกี่ยวข้อง ไม่มีการดำเนินการเข้ารหัสลับใดทำงาน
ความสอดคล้อง
หัวข้อที่มีชื่อว่า “ความสอดคล้อง”| ข้อความ | ข้อกำหนด | ข้อ | รหัสอ้างอิง (reference_id) |
|---|---|---|---|
| อ็อบเจกต์หน้ากำหนดขอบเขตของตนผ่านกล่องขอบเขต (MediaBox) | ISO 32000-2 | §7.7.3.3 | |
| สี่เหลี่ยมผืนผ้าของหน้าคือขอบเขตเนื้อหา | ISO 32000-2 | §7.7.3.3 | |
| ตำแหน่งวัดในพื้นที่ผู้ใช้ หนึ่งหน่วยคือ 1/72 นิ้ว | ISO 32000-2 | §8.3.2 |
สูตรนี้อ่านเรขาคณิตตามข้อกำหนดเรื่องกล่องหน้าและพื้นที่ผู้ใช้ของ ISO 32000-2 ที่อ้างถึง สูตรนี้ไม่อ้างความสอดคล้องกับ ISO 32000-2 แบบครอบคลุมทั้งหมด พื้นผิวการสอบถามเค้าโครงอาศัยข้อที่อ้างถึง