ความเสถียร: ทดลอง
PageBackfill: retained page buffer
ภาพรวมโดยย่อ
หัวข้อที่มีชื่อว่า “ภาพรวมโดยย่อ”Preview แบบ opt-in retained page buffer เปิดเป็นค่าเริ่มต้นปิด เมื่อมันปิด ตัว writer คือ streaming serializer อย่างที่มันเป็นมาตลอด — เหมือนกันทุกไบต์ เปิดมันเฉพาะเมื่อคุณจำเป็นต้องวาดลงบนหน้าก่อนหน้านี้จริง ๆ และอ่านรายการ fail-closed ด้านล่างก่อน
โดยค่าเริ่มต้น ตัว writer สตรีมหน้าและ flush ตามลำดับ; เมื่อหน้าถูก flush แล้ว มันไม่ สามารถวาดลงบนหน้านั้นได้อีก retained page buffer คือ opt-in ที่ถือหน้าที่ flush ไปแล้ว ไว้ เพื่อให้หน้าที่ flush ไปแล้วก่อนหน้านี้ถูก back-fill ได้ — วาดลงบนหน้าก่อนหน้า — ก่อนที่เอกสารจะถูก serialize การใช้งานคลาสสิกคือยอดรวมหรือกล่องสรุปที่คุณวางได้ หลังจากจัดหน้าถัด ๆ ไปแล้วเท่านั้น
การติดตั้ง
หัวข้อที่มีชื่อว่า “การติดตั้ง”composer require nextpdf/core:^3retained page buffer มาในแพ็กเกจ core Config::withRetainedPageBuffer() และเมท็อด
back-fill ของ Document เป็น @since 6.1.0 ค่าเริ่มต้นยังคงเป็น streaming writer
ADR-037 ซึ่งก่อนหน้านี้ได้เลื่อนความสามารถนี้ออกไป ตอนนี้ถูกบันทึกว่าได้นำมาใช้แล้ว
ภาพรวมเชิงแนวคิด
หัวข้อที่มีชื่อว่า “ภาพรวมเชิงแนวคิด”Config::withRetainedPageBuffer() ทำให้เอกสารเลือกใช้หน้าแบบ retained เมื่อเปิด
แล้ว Document::setActiveBackfillPage(int $pageIndex) จะเปลี่ยนทิศการวาดไปยังหน้า
ก่อนหน้าที่ flush ไปแล้ว; Document::endPageBackfill() คืนการวาดไปยังตำแหน่งต่อท้าย
ปกติ เนื้อหาที่คุณเขียนระหว่างการเรียกทั้งสองจะลงบนหน้าก่อนหน้า บัฟเฟอร์ถือหน้าไว้จน
ถึง save() ดังนั้น back-fill จึงถูกนำมาใช้ก่อนที่ cross-reference table และ trailer จะ
ถูกเขียน (ISO 32000-2 §7.5)
ขอบเขต fail-closed — การรวมที่ถูกปฏิเสธ
หัวข้อที่มีชื่อว่า “ขอบเขต fail-closed — การรวมที่ถูกปฏิเสธ”back-fill เป็นการดำเนินการแบบเข้าถึงสุ่ม (random-access) และคุณสมบัติเอกสารหลาย อย่างสันนิษฐานไบต์ที่ต่อท้ายอย่างเดียวและสตรีมไป retained page buffer ปฏิเสธที่จะ รวมกับสิ่งใดสิ่งหนึ่งในนั้น โดยไม่ขึ้นกับลำดับและก่อน serialization เพื่อให้มัน ไม่มีทาง ทำลายลายเซ็นหรือการอ้างความสอดคล้องอย่างเงียบ ๆ:
- ลายเซ็นดิจิทัล
- Tagged PDF (structure tree)
- PDF/A
- Linearization
- การแพ็ค object stream
- การเข้ารหัส
- โหมดการเรนเดอร์ CSS แบบ Safe
งบประมาณไบต์ที่ไม่บีบอัดต่อเอกสารจำกัดว่าบัฟเฟอร์อาจถือได้มากเพียงใด; เอกสารที่ เกินมันจะ hard-fail แทนที่จะบริโภคหน่วยความจำไม่จำกัด ค่าเริ่มต้น streaming ยังคง fail closed ในทันทีที่ผู้เรียกใช้พยายามสลับแบบเข้าถึงสุ่มโดยไม่มี opt-in — การเปิด บัฟเฟอร์เป็นวิธีเดียวที่จะได้ back-fill และมันเข้ากันไม่ได้กับคุณสมบัติข้างต้นโดยการ ออกแบบ
พื้นผิวของ API
หัวข้อที่มีชื่อว่า “พื้นผิวของ API”| สัญลักษณ์ | ตำแหน่ง | บทบาท |
|---|---|---|
Config::withRetainedPageBuffer(bool $enabled = true): self | src/Core/Config.php | ให้เอกสารเลือกใช้ retained page buffer |
Document::setActiveBackfillPage(int $pageIndex): static | src/Core/Document.php | เปลี่ยนทิศการวาดไปยังหน้าก่อนหน้าที่ flush ไปแล้ว |
Document::endPageBackfill(): static | src/Core/Document.php | คืนการวาดไปยังตำแหน่งต่อท้ายปกติ |
การพยายาม back-fill ที่ละเมิดการรวมที่ถูกปฏิเสธจะยกข้อยกเว้นการกำหนดค่าแบบมีชนิด ที่ขอบเขต ไม่ใช่เอกสารที่เสียหาย
ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว”จองตำแหน่งบนหน้าหนึ่ง เติมส่วนที่เหลือของเอกสาร แล้ว back-fill ตำแหน่งที่จองไว้ด้วย ค่าที่คำนวณตอนท้าย
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;use NextPDF\Core\Document;
$config = (new Config())->withRetainedPageBuffer();
$doc = Document::createStandalone($config);$doc->addPage(); // page 0 — leaves room for a grand total$doc->writeHtml('<h1>Invoice</h1>');
$doc->addPage(); // page 1 — line items$doc->writeHtml('<p>Line items…</p>');$total = 1234.56; // computed after laying out the items
$doc->setActiveBackfillPage(0); // draw back onto page 0$doc->writeHtml('<p>Grand total: ' . number_format($total, 2) . '</p>');$doc->endPageBackfill();
$doc->save(__DIR__ . '/invoice.pdf');ตัวอย่างโค้ด — สำหรับใช้งานจริง
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — สำหรับใช้งานจริง”ปิดบัฟเฟอร์ไว้สำหรับเอกสารที่ลงนาม tagged, PDF/A, linearized, เข้ารหัส หรือ object-stream ใด ๆ — เหล่านั้นคือการรวมที่บัฟเฟอร์ปฏิเสธพอดี เลือกเส้นทางหนึ่ง อย่างชัดเจน
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;use NextPDF\Core\Document;
function renderReport(bool $needsBackfill, bool $mustBeSigned): Document{ if ($needsBackfill && $mustBeSigned) { // The buffer refuses to combine with signing. Resolve the requirement // before building: pre-compute the value, or sign a separate pass. throw new \LogicException('Back-fill and signing are mutually exclusive.'); }
$config = new Config(); if ($needsBackfill) { $config = $config->withRetainedPageBuffer(); }
return Document::createStandalone($config);}กรณีขอบและข้อควรระวัง
หัวข้อที่มีชื่อว่า “กรณีขอบและข้อควรระวัง”- ปิดให้ผลลัพธ์เหมือนกันทุกไบต์ เมื่อบัฟเฟอร์ปิด ตัว writer สตรีมเหมือนเดิม
- ไม่รวมกับการลงนาม tagging, PDF/A, linearization, object stream, การเข้ารหัส และโหมด CSS แบบ Safe การปฏิเสธไม่ขึ้นกับลำดับและทำงานก่อน serialization วางแผนเอกสารสำหรับโหมดหนึ่งหรืออีกโหมดหนึ่ง
- งบประมาณไบต์ hard-fail บัฟเฟอร์ที่เก็บไว้มีขอบเขต; เอกสารที่เกินงบประมาณ ไบต์ที่ไม่บีบอัดจะล้มเหลวแทนที่จะโตอย่างไม่จำกัด
- จับคู่การเรียก ทุก
setActiveBackfillPage()ควรจับคู่กับendPageBackfill()เพื่อให้เนื้อหาภายหลังต่อท้ายตามปกติ - ค่าเริ่มต้น streaming ปฏิเสธการเข้าถึงสุ่ม เมื่อไม่มี opt-in การสลับแบบเข้าถึง สุ่มจะ fail closed บัฟเฟอร์เป็นเส้นทางเดียวที่รองรับ
ประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ประสิทธิภาพ”retained page buffer แลกหน่วยความจำกับความสามารถ back-fill: มันถือหน้าที่ flush
ไปแล้วไว้จนถึง save() โดยมีขอบเขตจากงบประมาณไบต์ที่ไม่บีบอัดต่อเอกสาร โปรไฟล์
หน่วยความจำแบนของ streaming writer ใช้บังคับเฉพาะเมื่อบัฟเฟอร์ปิด performance_budget
(wall_ms: 1500, peak_mb: 128) สะท้อนเพดานหน่วยความจำที่สูงขึ้นของเส้นทาง
retained
หมายเหตุด้านความปลอดภัย
หัวข้อที่มีชื่อว่า “หมายเหตุด้านความปลอดภัย”retained page buffer ไม่ขยายพื้นผิวอินพุต; มันเปลี่ยนเวลาที่ไบต์ถูก serialize ไม่ใช่สิ่งที่ ถูกรับเข้า การที่มันปฏิเสธการรวมกับการเข้ารหัสและการลงนามเป็นคุณสมบัติด้านความ ปลอดภัย: back-fill ไม่มีทางเปลี่ยนแปลงไบต์ที่ลงนามหรือเข้ารหัสภายหลังได้ เพราะ สองสิ่งนี้เปิดพร้อมกันไม่ได้ งบประมาณไบต์จำกัดหน่วยความจำเทียบกับเอกสารที่เป็นอันตราย
ความสอดคล้อง
หัวข้อที่มีชื่อว่า “ความสอดคล้อง”| ข้อความ | มาตรฐาน | ข้อ |
|---|---|---|
| ตัว writer serialize body, โครงสร้าง cross-reference และ trailer ในเวลา save | ISO 32000-2 | §7.5 |
นี่คือความสามารถแบบ preview NextPDF ปฏิเสธ back-fill buffer สำหรับเอกสารที่ลงนาม tagged, PDF/A, linearized, เข้ารหัส และ object-stream ดังนั้นมันจึงไม่อ้างความ สอดคล้องสำหรับโปรไฟล์เหล่านั้นผ่านเส้นทางนี้ ไม่มีการคัดลอกข้อความมาตรฐานซ้ำ
อะแดปเตอร์ Compat (TCPDF)
หัวข้อที่มีชื่อว่า “อะแดปเตอร์ Compat (TCPDF)”ตัว adapter ความเข้ากันได้ของ TCPDF เปิดเผยความสามารถนี้เป็นส่วนขยายของตัวสร้าง
สร้าง adapter ด้วย retainedPageBuffer: true จากนั้นการเรียก setPage() หรือ
lastPage() ที่เล็งไปยังหน้าก่อนหน้าจะมอบหมายให้ core back-fill แทนที่จะยก
UnsupportedFeatureException แบบ streaming อาร์กิวเมนต์ตัวสร้างนี้เป็น ส่วนขยาย
ของ NextPDF ไม่ใช่ความเท่าเทียมกับ TCPDF ดั้งเดิม — TCPDF ดั้งเดิมไม่มีแฟล็กเช่นนี้
การปฏิเสธแบบ fail-closed เดียวกันใช้บังคับ ดูหน้า retained-page-buffer ของ compat
adapter สำหรับรายละเอียดฝั่ง adapter