Triết lý thiết kế của NextPDF
Spec: ISO/IEC 25010 ISO/IEC 25010 Spec: ISO 32000-2 ISO 32000-2 Evidence: Design principle
Tổng quan nhanh
Phần tiêu đề “Tổng quan nhanh”Trang này trình bày các nguyên tắc làm thước đo cho mọi quyết định API của NextPDF. Chúng được cố ý giữ ở số lượng ít, vì một nguyên tắc mà bạn không thể nhớ ngay là nguyên tắc bạn khó áp dụng khi chịu áp lực.
Đây là trang bạn nên đọc đầu tiên. Các trang Insider_ khác cho thấy các nguyên tắc này phát huy tác dụng ở những vị trí cụ thể. Trang này gọi tên chúng để những trang còn lại dễ hiểu hơn.
Vì sao điều này quan trọng
Phần tiêu đề “Vì sao điều này quan trọng”PDF đã đủ lâu đời để mang trong mình những quy ước riêng, và đủ nghiêm ngặt để khiến việc phỏng đoán phải trả giá. Một chữ ký chỉ bao phủ đúng những byte mà nó bao phủ. Một phông chữ hoặc được nhúng, hoặc không. Một hồ sơ lưu trữ hoặc đứng vững, hoặc trượt một cuộc kiểm toán nhiều tháng sau đó, trước một người cần bằng chứng.
Một thư viện đứng trước một lựa chọn khi đầu vào không rõ ràng. Nó có thể âm thầm phỏng đoán, hoặc dừng lại và nói rõ điều đó. Cách thứ nhất có vẻ thân thiện hơn khi trình diễn. Nó cũng có thể khiến bạn phải gánh một sự cố trên môi trường production mà không để lại dấu vết gì về điều đã sai. NextPDF chọn cách thứ hai. Nó chấp nhận ấn tượng ban đầu kém yên tâm hơn để đổi lấy một kết quả có thể bảo vệ được. Các tiêu chuẩn chất lượng phần mềm gọi tên sự đánh đổi này một cách trực tiếp. Hành vi fail-safe là khả năng của một sản phẩm quay về trạng thái an toàn khi gặp lỗi thay vì tiếp tục ở một trạng thái không xác định ( Spec: ISO/IEC 25010, §3 ISO/IEC 25010 §3 ).
Tóm tắt ngắn gọn
Phần tiêu đề “Tóm tắt ngắn gọn”NextPDF được xây dựng trên năm nguyên tắc, theo thứ tự ưu tiên:
- Tường minh thắng ngầm định. Nếu ý định quan trọng, hãy nêu rõ. Engine không suy ra mức chữ ký, chế độ đầu ra hay mục tiêu tuân thủ từ ngữ cảnh.
- Lỗi nhanh, lỗi rõ ràng, lỗi sớm. Một đầu vào không hợp lệ bị từ chối trước khi ghi bất kỳ byte nào, kèm một thông báo gọi tên nguyên nhân.
- Lỗi là một phần của bề mặt API. Các lỗi cụ thể, có kiểu rõ ràng và chứa ngữ cảnh có cấu trúc — được thiết kế chứ không phải xuất hiện ngẫu nhiên.
- Ranh giới được nêu rõ, không phải để tự khám phá. Mọi tuyên bố đều nêu rõ điểm dừng của mình. “Cần nhưng chưa đủ” là một cụm từ mà NextPDF nêu ra một cách có chủ đích.
- Không có gì suy giảm trong im lặng. Engine không trả về một sản phẩm chỉ đúng một nửa nhưng trông như đã hoàn tất.
Mọi thứ còn lại — fluent builder, tài liệu dùng một lần, kiểu dữ liệu nghiêm ngặt — đều xuất phát từ những nguyên tắc này.
Cách NextPDF tiếp cận vấn đề này
Phần tiêu đề “Cách NextPDF tiếp cận vấn đề này”Các nguyên tắc không phải là khẩu hiệu. Chúng hiện diện dưới những hình thức cụ thể trong mã nguồn và củng cố lẫn nhau.
Bảng dưới đây ánh xạ mỗi nguyên tắc tới nơi bạn có thể thấy nó trong engine và cái giá phải trả khi thiếu nó.
| Nguyên tắc | Cách nó thể hiện trong NextPDF | Cái giá của điều ngược lại |
|---|---|---|
| Tường minh thắng ngầm định | setSignature(certInfo:, level:) nhận mức PAdES qua một đối số bắt buộc, có tên — không có mức “auto” | Một tài liệu được ký bằng một hồ sơ mà nghĩa vụ không yêu cầu, chỉ bị phát hiện ở thời điểm xác thực |
| Lỗi nhanh, lỗi rõ ràng | save() từ chối một đường dẫn stream-wrapper hoặc chứa null-byte trước khi kết xuất; setSignature() theo sau bởi save() sẽ ném ngoại lệ thay vì xuất ra một tệp chưa ký | Một thao tác ghi theo kiểu path-traversal, hoặc một tệp PDF “chưa ký nhưng được tin là đã ký” nằm trong kho lưu trữ |
| Lỗi là một phần của bề mặt API | Một ngoại lệ cơ sở trừu tượng, các lớp con có kiểu cụ thể, mỗi lớp đều cung cấp getContext() có cấu trúc cho log và APM | Một stack trace chung chung, cộng thêm cả một buổi chiều để đoán mò |
| Ranh giới được nêu rõ | Các bước kiểm tra tuân thủ ngay trong tiến trình trả về các phát hiện và nói rõ rằng kết luận cuối cùng thuộc về một trình xác thực độc lập | Một kết luận kiểu “không có ngoại lệ, nên chắc chắn là tuân thủ” mà một kiểm toán viên bác bỏ |
| Không có gì suy giảm trong im lặng | Luồng dấu thời gian lưu trữ từ chối trả về một hồ sơ còn dang dở thay vì xuất ra một hồ sơ thiếu dictionary bắt buộc của nó | Một hồ sơ xác thực dài hạn thực chất, trong im lặng, lại không phải như vậy |
Khi đọc các nguyên tắc cùng nhau, một lập trường duy nhất hiện ra: engine thà đưa cho bạn một câu “không” trung thực còn hơn một câu “có thể” đầy tự tin. Đó không phải là sự bi quan. Lập trường đó thừa nhận rằng một tệp PDF thường là một bằng chứng pháp lý. Một bằng chứng pháp lý sai còn tệ hơn một bằng chứng chưa từng được tạo ra.
Bằng chứng nói gì
Phần tiêu đề “Bằng chứng nói gì”Trang này là một tuyên bố Evidence: Design principle : các nguyên tắc là những quyết định có chủ đích, được lập luận chứ không phải được đo lường. Khi một nguyên tắc đã có tên gọi trong một lĩnh vực bên ngoài, trang này neo lập luận vào đó để nó không chỉ là một ý kiến nội bộ.
- Lập trường “từ chối thay vì tiếp tục trong một trạng thái không xác định” chính là thuộc tính chất lượng fail-safe trong Spec: ISO/IEC 25010 ISO/IEC 25010 §3 — một sản phẩm tự đưa mình về điều kiện an toàn khi gặp lỗi. Fault tolerance, thuộc cùng nhóm, là mức độ mà một hệ thống tiếp tục vận hành như dự định bất chấp các lỗi. NextPDF hướng nỗ lực đó vào việc phát hiện rồi dừng lại, chứ không phải che giấu lỗi.
- Lập trường “nêu rõ ranh giới trước khi áp dụng” chính là appropriateness recognizability ( Spec: ISO/IEC 25010, §3.26 ISO/IEC 25010 §3.26 ): khả năng đánh giá mức độ phù hợp từ tài liệu và ấn tượng ban đầu.
- Lý do đặc thù của PDF khiến tất cả những điều này quan trọng là Spec: ISO 32000-2, §12.8 ISO 32000-2 §12.8 : byte range của một chữ ký bảo vệ đúng những byte mà nó bao phủ và không gì hơn, nên một engine “tốt bụng” viết lại hoặc phỏng đoán trên một tài liệu đã ký thì chẳng giúp ích gì cả.
Mỗi nguyên tắc được minh họa dựa trên mã nguồn engine thực tế trên trang riêng của chúng — Một API từ chối phỏng đoán và Lỗi như một tính năng mang theo Evidence: Code-backed làm bằng chứng. Trang này trả lời vì sao; những trang đó trả lời điều gì.
Ví dụ thực tế
Phần tiêu đề “Ví dụ thực tế”Các nguyên tắc có thể thấy ngay trong vài dòng sử dụng thông thường. Lời gọi chữ ký nêu rõ ý định một cách tường minh. Engine từ chối sớm thay vì xuất ra một thứ dễ gây hiểu lầm.
<?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());}Trọng tâm ở đây không phải là cơ chế chữ ký. Có thể thấy ba nguyên tắc trong một đoạn mã: ý định được nêu rõ (level:), lỗi xảy ra sớm và được gọi tên, và engine từ chối tạo ra một tài liệu nói sai về chính trạng thái của nó.
Hiểu lầm thường gặp
Phần tiêu đề “Hiểu lầm thường gặp”Cách hiểu sai phổ biến nhất là cho rằng các nguyên tắc này làm NextPDF “khó dùng hơn”. Thực ra, chúng làm nó khó dùng sai hơn. Một đối số bắt buộc nghĩa là bớt đi một giá trị mặc định âm thầm có thể khiến bạn bất ngờ. Một ngoại lệ xảy ra sớm nghĩa là bớt đi một sản phẩm hỏng trong kho lưu trữ. Điểm cản trở được đặt có chủ đích ở nơi cái giá của sai lầm còn rẻ — tại điểm gọi, trong lúc phát triển — thay vì ở nơi nó đắt giá: trên môi trường production, trong một cuộc kiểm toán, tại tòa án.
Cách hiểu sai thứ hai là cho rằng “có quan điểm” nghĩa là “thiếu linh hoạt”. Không phải vậy. Engine có quan điểm về tính đúng đắn và ý định, chứ không phải về tài liệu của bạn. Bạn vẫn hoàn toàn kiểm soát bố cục, nội dung, phông chữ và cấu trúc. Những quan điểm đó xoay quanh việc không phỏng đoán thay cho bạn ở những nơi mà phỏng đoán là không an toàn.
Giới hạn và ranh giới
Phần tiêu đề “Giới hạn và ranh giới”Trang này nêu rõ ý định thiết kế. Bản thân nó không phải là một đặc tả hành vi. Các nguyên tắc mô tả cách các quyết định được đưa ra, chứ không phải lời bảo đảm cho bất kỳ phương thức cụ thể nào. Hợp đồng chính xác của mỗi phương thức nằm trong tài liệu tham chiếu và trong trang Insider_ riêng của nó, cùng mức bằng chứng tương ứng.
Các nguyên tắc cũng không phải là những định luật vật lý tuyệt đối. Chúng là những ưu tiên, được áp dụng có cân nhắc. Khi hai nguyên tắc xung đột (một sự từ chối nghiêm khắc hơn so với một mặc định khoan dung hơn), thứ tự ưu tiên ở trên là yếu tố quyết định. Một mô-đun cụ thể vẫn có thể ghi lại một ngoại lệ có lý do. Khi điều đó xảy ra, ngoại lệ ấy được ghi lại bằng văn bản, chứ không được ngầm giả định.
Cuối cùng, “nguyên tắc thiết kế” là cơ sở bằng chứng ở đây một cách có chủ đích. Trang này lập luận. Nó không đo điểm chuẩn. Những tuyên bố cần một con số, một bài kiểm thử hay một điều khoản để củng cố sẽ được đưa ra trên các trang sở hữu bằng chứng đó, không phải ở đây.
Tài liệu liên quan
Phần tiêu đề “Tài liệu liên quan”- Một API từ chối phỏng đoán — các nguyên tắc về ý định tường minh và lỗi nhanh, được minh họa bằng API thực tế.
- Lỗi như một tính năng — hệ phân cấp ngoại lệ có kiểu như một bề mặt được thiết kế.
- Nền tảng PHP 8.4 — các tính năng ngôn ngữ cho phép thực thi các nguyên tắc này, thay vì chỉ trông mong.
Thuật ngữ
Phần tiêu đề “Thuật ngữ”- Nguyên tắc thiết kế (mức bằng chứng) — một trang trong đó các tuyên bố là những quyết định thiết kế có chủ đích, được lập luận từ ý định và các tiêu chuẩn xác nhận, thay vì được đo bằng một điểm chuẩn hay một bài kiểm thử đơn lẻ.
- Fail-safe — một thuộc tính chất lượng phần mềm: khi gặp lỗi, sản phẩm quay về trạng thái an toàn thay vì tiếp tục ở một trạng thái không xác định. Đó là lý do NextPDF từ chối thay vì phỏng đoán.
- Fail fast — từ chối một đầu vào không hợp lệ tại điểm sớm nhất có thể, kèm theo một nguyên nhân rõ ràng, thay vì tiếp tục rồi báo lỗi một cách mơ hồ sau này.
- PAdES — PDF Advanced Electronic Signatures, nhóm hồ sơ ETSI để ký các tài liệu PDF (B-B, B-T, B-LT, B-LTA). Được giải thích đầy đủ tại đây ở lần xuất hiện đầu tiên; phần chuyên sâu nằm trên các trang về ký.
- Cần nhưng chưa đủ — một cách diễn đạt có chủ đích, dùng khi một bước kiểm tra ngay trong tiến trình là một tín hiệu thực sự nhưng không phải là kết luận về tuân thủ; quyết định có thẩm quyền thuộc về một trình xác thực độc lập.