ปรัชญาการออกแบบของ NextPDF
Spec: ISO/IEC 25010 ISO/IEC 25010 Spec: ISO 32000-2 ISO 32000-2 Evidence: Design principle
ภาพรวมโดยย่อ
หัวข้อที่มีชื่อว่า “ภาพรวมโดยย่อ”หน้านี้ระบุหลักการที่ใช้เป็นเกณฑ์สำหรับทุกการตัดสินใจของ API ใน NextPDF หลักการเหล่านี้มีจำนวนน้อยโดยตั้งใจ เพราะหลักการที่จำไม่ได้ย่อมนำไปใช้ไม่ได้เมื่ออยู่ภายใต้ความกดดัน
หน้านี้เป็นหน้าที่ควรอ่านเป็นอันดับแรก หน้า Insider_ อื่นๆ แสดงให้เห็นว่าหลักการเหล่านี้ทำงานอย่างไรในจุดที่เจาะจง หน้านี้ตั้งชื่อให้หลักการเหล่านั้น เพื่อให้เข้าใจหน้าที่เหลือได้ง่ายขึ้น
ทำไมเรื่องนี้จึงสำคัญ
หัวข้อที่มีชื่อว่า “ทำไมเรื่องนี้จึงสำคัญ”PDF มีประวัติยาวนานพอที่จะมีจุดยืนของตัวเอง และเข้มงวดพอที่จะลงโทษการคาดเดา ลายเซ็นครอบคลุมไบต์เฉพาะช่วงที่ครอบคลุมไว้อย่างแม่นยำ ฟอนต์มีสองสถานะคือถูกฝังไว้หรือไม่ได้ฝังไว้ โปรไฟล์สำหรับการเก็บถาวรมีผลลัพธ์เพียงสองแบบคือผ่านหรือไม่ผ่านการตรวจสอบในอีกหลายเดือนถัดมา ต่อหน้าผู้ที่ต้องการหลักฐาน
เมื่ออินพุตคลุมเครือ ไลบรารีมีทางเลือกว่าจะคาดเดาแล้วปล่อยผ่านเงียบๆ หรือจะหยุดและแจ้งให้ทราบ ตัวเลือกแรกดูเป็นมิตรกว่าในการสาธิต แต่ก็อาจทำให้ต้องเสียค่าใช้จ่ายจากเหตุการณ์ในระบบจริงโดยไม่มีร่องรอยว่าอะไรผิดพลาด NextPDF เลือกตัวเลือกที่สอง NextPDF ยอมรับความประทับใจแรกที่ดูเป็นมิตรน้อยกว่า เพื่อแลกกับผลลัพธ์ที่ปกป้องได้ มาตรฐานคุณภาพซอฟต์แวร์เรียกการแลกเปลี่ยนนี้โดยตรงว่า พฤติกรรม fail-safe คือความสามารถของผลิตภัณฑ์ในการย้อนกลับสู่สถานะปลอดภัยเมื่อเกิดความล้มเหลว แทนที่จะทำงานต่อในสถานะที่ไม่นิยาม ( Spec: ISO/IEC 25010, §3 ISO/IEC 25010 §3 )
ฉบับย่อ
หัวข้อที่มีชื่อว่า “ฉบับย่อ”NextPDF สร้างขึ้นบนหลักการห้าข้อ เรียงตามลำดับความสำคัญดังนี้
- การระบุชัดเจนเหนือกว่าการอนุมานโดยปริยาย หากเจตนาเป็นเรื่องสำคัญ ต้องระบุออกมา เอนจินจะไม่อนุมานระดับลายเซ็น โหมดเอาต์พุต หรือเป้าหมายความสอดคล้องจากบริบท
- ล้มเหลวเร็ว ล้มเหลวให้ดัง ล้มเหลวแต่เนิ่นๆ อินพุตที่ไม่ถูกต้องจะถูกปฏิเสธก่อนที่จะเขียนไบต์ใดๆ ลงไป พร้อมข้อความที่ระบุสาเหตุ
- ข้อผิดพลาดคือพื้นผิวของ API ความล้มเหลวมีความเฉพาะเจาะจง มีชนิดที่กำหนด และมีบริบทแบบมีโครงสร้างติดมาด้วย — เป็นสิ่งที่ออกแบบไว้ ไม่ใช่เกิดขึ้นโดยบังเอิญ
- ขอบเขตถูกระบุไว้ ไม่ใช่ปล่อยให้ค้นพบเอง ทุกข้อกล่าวอ้างจะระบุขอบเขตสิ้นสุดของตน “จำเป็นแต่ไม่เพียงพอ” เป็นวลีที่ NextPDF ระบุไว้โดยเจตนา
- ไม่มีสิ่งใดเสื่อมลงอย่างเงียบๆ เอนจินจะไม่คืนค่าผลงานที่ถูกต้องเพียงครึ่งเดียวซึ่งดูเหมือนเสร็จสมบูรณ์
สิ่งที่เหลือทั้งหมด — fluent builder, disposable document, การกำหนดชนิดแบบเข้มงวด — ล้วนสืบเนื่องจากหลักการเหล่านี้
NextPDF นำหลักการเหล่านี้ไปใช้อย่างไร
หัวข้อที่มีชื่อว่า “NextPDF นำหลักการเหล่านี้ไปใช้อย่างไร”หลักการเหล่านี้ไม่ใช่คำขวัญ แต่ปรากฏเป็นรูปธรรมในโค้ดต้นฉบับ และเสริมกันและกัน
ตารางด้านล่างจับคู่หลักการแต่ละข้อกับจุดที่เห็นได้ในเอนจิน และต้นทุนที่จะเกิดขึ้นหากไม่มีหลักการนั้น
| หลักการ | ปรากฏใน NextPDF อย่างไร | ต้นทุนของการทำตรงกันข้าม |
|---|---|---|
| การระบุชัดเจนเหนือกว่าการอนุมานโดยปริยาย | setSignature(certInfo:, level:) รับระดับ PAdES เป็นอาร์กิวเมนต์แบบมีชื่อที่จำเป็นต้องระบุ — ไม่มีระดับ “auto” | เอกสารที่ลงนามด้วยโปรไฟล์ซึ่งไม่ได้กำหนดข้อผูกพันไว้ และมาถูกค้นพบในขั้นตอนตรวจสอบความถูกต้อง |
| ล้มเหลวเร็ว ล้มเหลวให้ดัง | save() ปฏิเสธเส้นทางที่เป็น stream-wrapper หรือมี null-byte ก่อนการเรนเดอร์ การเรียก setSignature() ตามด้วย save() จะโยนข้อยกเว้นแทนที่จะสร้างไฟล์ที่ไม่ได้ลงนาม | การเขียนไฟล์ผ่าน path-traversal หรือ PDF ที่ “ไม่ได้ลงนามแต่เชื่อว่าลงนามแล้ว” ในคลังเอกสาร |
| ข้อผิดพลาดคือพื้นผิวของ API | ข้อยกเว้นฐานเชิงนามธรรมหนึ่งตัว พร้อมคลาสย่อยที่มีชนิดเฉพาะเจาะจง โดยแต่ละตัวเปิดเผย getContext() แบบมีโครงสร้างสำหรับล็อกและ APM | stack trace ทั่วไปและเวลาทั้งบ่ายที่เสียไปกับการคาดเดา |
| ขอบเขตถูกระบุไว้ | การตรวจสอบความสอดคล้องภายในกระบวนการจะคืนค่าผลการตรวจพบ และระบุเป็นถ้อยคำว่าคำตัดสินสุดท้ายเป็นหน้าที่ของผู้ตรวจสอบอิสระ | ข้อสรุปแบบ “ไม่มีข้อยกเว้น ดังนั้นต้องสอดคล้องแน่นอน” ที่ผู้ตรวจสอบพิสูจน์ว่าไม่จริง |
| ไม่มีสิ่งใดเสื่อมลงอย่างเงียบๆ | เส้นทางการประทับเวลาแบบเก็บถาวรจะปฏิเสธที่จะคืนค่าโปรไฟล์ที่เขียนเพียงครึ่งเดียว แทนที่จะสร้างโปรไฟล์ที่ขาด dictionary ที่จำเป็น | โปรไฟล์การตรวจสอบระยะยาวที่จริงๆ แล้วไม่ใช่โปรไฟล์ดังกล่าว แต่ไม่มีใครรู้ |
เมื่ออ่านหลักการเหล่านี้รวมกัน จุดยืนหนึ่งเดียวจะปรากฏชัด นั่นคือ เอนจินยอมตอบว่า “ไม่ได้” อย่างซื่อตรง มากกว่าจะตอบว่า “อาจจะ” อย่างมั่นใจ นี่ไม่ใช่การมองโลกในแง่ร้าย แต่เป็นการตระหนักว่า PDF มักใช้เป็นเอกสารทางกฎหมาย และเอกสารทางกฎหมายที่ผิดพลาดเลวร้ายยิ่งกว่าเอกสารที่ไม่เคยถูกสร้างขึ้นเลย
หลักฐานบอกอะไร
หัวข้อที่มีชื่อว่า “หลักฐานบอกอะไร”หน้านี้เป็นข้อความแบบ Evidence: Design principle กล่าวคือ หลักการเหล่านี้เป็นการตัดสินใจในการออกแบบโดยเจตนา สนับสนุนด้วยเหตุผลมากกว่าผลการวัด ในกรณีที่หลักการหนึ่งมีชื่อเรียกในสาขาความรู้ภายนอก หน้านี้จะอ้างอิงชื่อนั้น เพื่อให้เหตุผลไม่เป็นเพียงความเห็นภายในองค์กรเท่านั้น
- จุดยืนที่ว่า “ปฏิเสธแทนที่จะทำงานต่อในสถานะที่ไม่นิยาม” คือคุณสมบัติด้านคุณภาพแบบ fail-safe ใน Spec: ISO/IEC 25010 ISO/IEC 25010 §3 — ผลิตภัณฑ์ที่พาตัวเองกลับสู่สภาวะปลอดภัยเมื่อเกิดความล้มเหลว Fault tolerance ซึ่งอยู่ในตระกูลเดียวกัน คือระดับที่ระบบยังคงทำงานตามที่ตั้งใจไว้แม้จะเกิดข้อบกพร่อง NextPDF มุ่งความพยายามนั้นไปที่การตรวจจับและหยุดการทำงาน ไม่ใช่การปกปิดข้อบกพร่อง
- จุดยืนที่ว่า “ระบุขอบเขตก่อนการนำมาใช้” คือ appropriateness recognizability ( Spec: ISO/IEC 25010, §3.26 ISO/IEC 25010 §3.26 ) หรือความสามารถในการตัดสินความเหมาะสมจากเอกสารประกอบและความประทับใจแรก
- เหตุผลเฉพาะของ PDF ที่ทำให้ทั้งหมดนี้สำคัญคือ Spec: ISO 32000-2, §12.8 ISO 32000-2 §12.8 นั่นคือ byte range ของลายเซ็นปกป้องไบต์เฉพาะช่วงที่ครอบคลุมไว้อย่างแม่นยำและไม่เกินกว่านั้น ดังนั้นเอนจินที่ “หวังดี” แต่เขียนทับหรือคาดเดารอบๆ เอกสารที่ลงนามแล้วจึงไม่ได้ช่วยเหลืออะไรเลย
หลักการแต่ละข้อได้รับการสาธิตผ่านโค้ดต้นฉบับของเอนจินจริงในหน้าของแต่ละหลักการ — An API that refuses to guess และ Errors as a feature เป็นหน้าที่นำเสนอหลักฐานแบบ Evidence: Code-backed หน้านี้คือ “เพราะอะไร” ส่วนหน้าเหล่านั้น คือ “อะไร”
ตัวอย่างการใช้งานจริง
หัวข้อที่มีชื่อว่า “ตัวอย่างการใช้งานจริง”หลักการเหล่านี้มองเห็นได้ในโค้ดการใช้งานทั่วไปเพียงไม่กี่บรรทัด การเรียกใช้ลายเซ็นระบุเจตนาอย่างชัดเจน เอนจินจะปฏิเสธแต่เนิ่นๆ แทนที่จะสร้างสิ่งที่ทำให้เข้าใจผิด
<?php
declare(strict_types=1);
use NextPDF\Core\Document;use NextPDF\Exception\NotImplementedException;use NextPDF\Security\Signature\CertificateInfo;use NextPDF\Security\Signature\SignatureLevel;
$document = Document::createStandalone();$document->setTitle('Service Agreement 2026-0042');$document->addPage();$document->setFont('helvetica', '', 12);$document->cell(0, 10, 'This agreement is configured for a PAdES signature.', newLine: true);
// Explicit beats implicit: the PAdES level is a required, named argument.// There is no inferred or "auto" level.$document->setSignature( certInfo: new CertificateInfo( certificate: $certificatePem, privateKey: $privateKeyPem, ), level: SignatureLevel::PAdES_B_B,);
try { // Fail fast, no silent degradation: rather than emit an UNSIGNED file // that the caller believes setSignature() signed, the high-level path // refuses and names the supported route. $document->save('/srv/output/agreement.pdf');} catch (NotImplementedException $e) { // The message identifies the feature and the follow-up, not a stack // trace: "... is not implemented in this release. <actionable follow-up>" error_log($e->getMessage());}ประเด็นไม่ได้อยู่ที่กลไกของลายเซ็น หลักการสามข้อสังเกตได้ในโค้ดสั้นๆ ชิ้นเดียว นั่นคือ เจตนาถูกระบุ (level:) ความล้มเหลวเกิดขึ้นแต่เนิ่นๆ พร้อมระบุสาเหตุ และเอนจินปฏิเสธที่จะสร้างเอกสารที่จะโกหกเกี่ยวกับสถานะของตัวเอง
ความเข้าใจผิดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ความเข้าใจผิดที่พบบ่อย”การตีความผิดที่พบบ่อยที่สุดคือ หลักการเหล่านี้ทำให้ NextPDF “ใช้งานยากขึ้น” แท้จริงแล้วหลักการเหล่านี้ทำให้ใช้งาน อย่างผิดๆ ได้ยากขึ้นต่างหาก อาร์กิวเมนต์ที่จำเป็นต้องระบุช่วยลดค่าเริ่มต้นแบบเงียบๆ ที่อาจทำให้คุณประหลาดใจไปหนึ่งรายการ ข้อยกเว้นที่เกิดขึ้นแต่เนิ่นๆ หมายถึงผลลัพธ์ที่เสียหายในคลังเอกสารน้อยลงไปหนึ่งชิ้น ความฝืดในการใช้งานถูกวางไว้โดยเจตนาในจุดที่ความผิดพลาดมีต้นทุนต่ำ — ที่จุดเรียกใช้ระหว่างการพัฒนา — แทนที่จะเป็นจุดที่มีต้นทุนสูง นั่นคือ ในระบบจริง ในการตรวจสอบ หรือในชั้นศาล
การตีความผิดอย่างที่สองคือ “การมีจุดยืน” หมายถึง “ไม่ยืดหยุ่น” ซึ่งไม่เป็นเช่นนั้น เอนจินมีจุดยืนเกี่ยวกับ ความถูกต้องและเจตนา ไม่ใช่เกี่ยวกับเอกสารของคุณ คุณยังคงควบคุมเค้าโครง เนื้อหา ฟอนต์ และโครงสร้างได้อย่างสมบูรณ์ จุดยืนเหล่านี้หมายถึงการไม่คาดเดาแทนคุณในจุดที่การคาดเดาไม่ปลอดภัย
ข้อจำกัดและขอบเขต
หัวข้อที่มีชื่อว่า “ข้อจำกัดและขอบเขต”หน้านี้ระบุเจตนาในการออกแบบ หน้านี้ไม่ใช่ข้อกำหนดด้านพฤติกรรมในตัวเอง หลักการเหล่านี้อธิบายวิธีการตัดสินใจ ไม่ใช่การรับประกันเกี่ยวกับเมท็อดใดเมท็อดหนึ่ง สัญญาที่แม่นยำของแต่ละเมท็อดอยู่ในเอกสารอ้างอิงและในหน้า Insider_ ของแต่ละเมท็อด พร้อมระดับหลักฐานของหน้านั้นๆ
หลักการเหล่านี้ก็ไม่ใช่กฎฟิสิกส์ที่ตายตัวเช่นกัน หลักการเหล่านี้เป็นลำดับความสำคัญ ซึ่งนำไปใช้โดยอาศัยวิจารณญาณ ในกรณีที่หลักการสองข้อขัดแย้งกัน (การปฏิเสธที่เข้มงวดกว่ากับค่าเริ่มต้นที่ผ่อนปรนกว่า) ลำดับความสำคัญข้างต้นคือตัวชี้ขาด โมดูลเฉพาะยังคงอาจระบุข้อยกเว้นที่มีเหตุผลไว้ในเอกสารได้ เมื่อเป็นเช่นนั้น ข้อยกเว้นดังกล่าวจะถูกบันทึกไว้ ไม่ใช่ถูกสันนิษฐานเอา
ท้ายที่สุด “หลักการออกแบบ” คือระดับหลักฐานในหน้านี้โดยเจตนา หน้านี้โต้แย้งด้วยเหตุผล หน้านี้ไม่ได้วัดประสิทธิภาพเชิงเปรียบเทียบ ข้อกล่าวอ้างที่ต้องใช้ตัวเลข การทดสอบ หรือข้อกำหนดมาสนับสนุนจะปรากฏในหน้าที่รับผิดชอบหลักฐานนั้น ไม่ใช่ในหน้านี้
เอกสารที่เกี่ยวข้อง
หัวข้อที่มีชื่อว่า “เอกสารที่เกี่ยวข้อง”- An API that refuses to guess — หลักการเรื่องเจตนาที่ระบุชัดเจนและการล้มเหลวเร็ว ซึ่งแสดงให้เห็นกับ API จริง
- Errors as a feature — ลำดับชั้นของข้อยกเว้นแบบมีชนิดกำหนดในฐานะพื้นผิวที่ออกแบบไว้
- The PHP 8.4 foundations — คุณสมบัติของภาษาที่ทำให้สามารถบังคับใช้หลักการเหล่านี้ได้จริงแทนที่จะได้แต่หวัง
อภิธานศัพท์
หัวข้อที่มีชื่อว่า “อภิธานศัพท์”- หลักการออกแบบ (ระดับหลักฐาน) — หน้าที่ข้อกล่าวอ้างเป็นการตัดสินใจในการออกแบบโดยเจตนา ซึ่งโต้แย้งจากเจตนาและมาตรฐานที่รองรับ มากกว่าจะวัดด้วยการทดสอบเชิงเปรียบเทียบหรือการทดสอบรายกรณี
- Fail-safe — คุณสมบัติด้านคุณภาพซอฟต์แวร์ กล่าวคือ เมื่อเกิดความล้มเหลว ผลิตภัณฑ์จะย้อนกลับสู่สถานะปลอดภัยแทนที่จะทำงานต่อในสถานะที่ไม่นิยาม และเป็นเหตุผลที่ NextPDF เลือกปฏิเสธแทนที่จะคาดเดา
- Fail fast — การปฏิเสธอินพุตที่ไม่ถูกต้องตั้งแต่จุดที่เร็วที่สุดเท่าที่จะเป็นไปได้ พร้อมสาเหตุที่ชัดเจน แทนที่จะดำเนินการต่อแล้วล้มเหลวอย่างคลุมเครือในภายหลัง
- PAdES — PDF Advanced Electronic Signatures ซึ่งเป็นตระกูลโปรไฟล์ของ ETSI สำหรับการลงนามเอกสาร PDF (B-B, B-T, B-LT, B-LTA) มีการขยายความไว้ที่นี่เมื่อใช้ครั้งแรก ส่วนรายละเอียดเชิงลึกครอบคลุมอยู่ในหน้าว่าด้วยการลงนาม
- จำเป็นแต่ไม่เพียงพอ — ถ้อยคำที่ใช้โดยเจตนาเมื่อการตรวจสอบภายในกระบวนการเป็นสัญญาณที่แท้จริงแต่ไม่ใช่คำตัดสินความสอดคล้อง คำตัดสินอย่างเป็นทางการเป็นหน้าที่ของผู้ตรวจสอบอิสระ