Một engine, mọi framework
Spec: PSR-11 Container, §1.1.2PSR-11 Container §1.1.2Spec: PSR-4 Autoloader, §3PSR-4 Autoloader §3
Tổng quan nhanh
Phần tiêu đề “Tổng quan nhanh”Phần lớn các hệ thống PHP đang lớn dần rốt cuộc đều dùng nhiều hơn một framework. NextPDF là một engine PDF gặp gỡ từng framework theo cách riêng của nó: các bridge thuần idiom cho Laravel, Symfony, và CodeIgniter, cùng một lối đi standalone cho mã không chạy trong framework nào cả. Mô hình tài liệu được dùng chung. Chỉ có cách bạn gọi nó là thay đổi.
Vì sao điều này quan trọng
Phần tiêu đề “Vì sao điều này quan trọng”Một thư viện PDF khác nhau cho mỗi stack là một thứ thuế âm thầm. Mỗi thư viện có những điểm kỳ quặc riêng, cách xử lý phông chữ riêng, quan niệm riêng về thế nào là hợp lệ. Một hóa đơn kết xuất đúng từ service Laravel có thể kết xuất khác đi một cách tinh vi từ worker Symfony, bởi vì một thư viện khác đã vẽ nó. Bây giờ mục tiêu lưu trữ, vị trí đặt chữ ký, và các thẻ trợ năng của bạn phụ thuộc vào nhóm nào đã xuất bản tài liệu. Báo cáo lỗi ghi “tệp PDF bị sai”, và câu trả lời phụ thuộc vào engine nào trong ba engine đã tạo ra nó.
Chuẩn hóa về một engine làm gọn lại bề mặt đó. Có một nơi duy nhất quyết định một profile PDF/A, một pipeline phông chữ để chứng nhận, một công cụ xác thực để tin tưởng. Framework mà bạn tình cờ đang dùng thôi không còn là một biến số trong việc tài liệu có đúng hay không.
Tóm tắt nhanh
Phần tiêu đề “Tóm tắt nhanh”- Engine lõi độc lập với framework.
nextpdf/corekhông biết gì về HTTP, định tuyến, hay việc nối dây container. Nó là một engine PDF 2.0 và không gì hơn. - Mỗi bridge thích nghi, nó không hiện thực lại. Các gói Laravel, Symfony, và CodeIgniter trao cho bạn một facade hoặc factory, một helper phản hồi HTTP, và một lối tạo theo hàng đợi hoặc bất đồng bộ — trên cùng một engine.
- Một bridge đi theo framework của bạn, không phải tài liệu của bạn. Nó thay đổi cách bạn gọi engine, không bao giờ thay đổi những gì engine có thể tạo ra.
- Standalone luôn có sẵn. Một công cụ CLI, một daemon, hay một thư viện không có framework nào để bridge từ đó; nó dựng một tài liệu trực tiếp.
- Một mô hình tài liệu đi xuyên cả bốn lối. Cùng các value object, enum, và hợp đồng kết quả đầu ra xuất hiện ở mọi nơi, nên một tài liệu di chuyển giữa các điểm gọi mà không đổi.
NextPDF tiếp cận điều này như thế nào
Phần tiêu đề “NextPDF tiếp cận điều này như thế nào”Kiến trúc là một sự tách bạch có chủ đích. Engine là tài sản; bridge là một adapter mỏng nói theo idiom của một framework. Một bridge đăng ký một namespace nhỏ trên phần lõi dùng chung thông qua cơ chế autoload tiêu chuẩn (Spec: PSR-4 Autoloader, §3PSR-4 Autoloader §3) và trao lại một tài liệu thông qua hợp đồng container (Spec: PSR-11 Container, §1.1.2PSR-11 Container §1.1.2). Hợp đồng đó là người hùng thầm lặng ở đây: nó cho phép hai lần phân giải cùng một định danh trả về các thực thể khác nhau, và đó đúng là cách một bridge trao cho bạn một tài liệu tươi mới, dùng một lần cho mỗi request trong khi vẫn giữ registry phông chữ đã phân tích và cache hình ảnh dưới dạng singleton trên toàn tiến trình. Các worker sống lâu — Octane, RoadRunner, Swoole, Messenger — nhờ kiến trúc mà được phân bổ đều chi phí phân tích phông chữ mà không rò rỉ trạng thái qua các request.
Bốn idiom chỉ khác nhau ở bề mặt:
- Core enginenextpdf/core — the framework-agnostic PDF 2.0 engine; the single shared document model, value objects, and output contract.
- Laravel bridgenextpdf/laravel — auto-discovered provider, a Pdf facade, a PdfResponse helper, and a queued GeneratePdfJob.
- Symfony bridgenextpdf/symfony — an auto-registered bundle, an injectable PdfFactory, a PdfResponse, and an optional Messenger handler.
- CodeIgniter bridgenextpdf/codeigniter — a service and pdf() helper, a Pdf library over a disposable Document, and a PdfResponse.
- StandaloneNo framework to bridge from — construct a Document directly in a CLI tool, daemon, or library.
Đọc sơ đồ từ trái sang phải và bài học chính là sự đối xứng. Mọi bề mặt đều phân
giải về cùng một Document. Facade Laravel, factory Symfony, service
CodeIgniter, và constructor standalone là bốn cánh cửa vào cùng một căn phòng.
Ví dụ thực tế
Phần tiêu đề “Ví dụ thực tế”Cùng ba dòng thể hiện ý định, diễn đạt trong từng idiom. Phần thân dựng nên tài liệu — trang, phông chữ, ô, ký, tuân thủ — là giống hệt nhau ở cả bốn, bởi vì nó là cùng một engine.
<?php
declare(strict_types=1);
// Laravel — resolve a fresh document from the container.use NextPDF\Contracts\PdfDocumentInterface;$document = app(PdfDocumentInterface::class);
// Symfony — inject the factory, then ask it for a document.use NextPDF\Symfony\Service\PdfFactory;$document = $factory->create(); // PdfFactory injected into your service
// CodeIgniter — pull it from the Services layer.use NextPDF\CodeIgniter\Config\Services;$document = Services::pdfDocument();
// Standalone — no framework; construct it directly.use NextPDF\Core\Document;$document = Document::createStandalone();
// From here, the code is identical regardless of how $document arrived.$document->addPage();$document->cell(0, 10, 'One engine, every framework', newLine: true);$bytes = $document->getPdfData();Những dòng đầu là điểm khác biệt duy nhất. Mọi thứ phía sau đều khả chuyển: di chuyển một service dựng tài liệu từ Symfony sang một worker standalone và mã kết xuất không đổi, bởi vì hợp đồng mà nó phụ thuộc vào đã không đổi.
Hiểu lầm thường gặp
Phần tiêu đề “Hiểu lầm thường gặp”Giả định thường gặp là bridge của framework mở khóa các khả năng — rằng xác thực
chữ ký dài hạn hay hóa đơn điện tử có cấu trúc xuất hiện chỉ vì bạn đã cài
nextpdf/laravel thay vì gọi engine trực tiếp. Không phải vậy. Một bridge thay
đổi điểm gọi, không bao giờ thay đổi phạm vi của engine. Các khả năng lõi như kết
quả đầu ra PDF/A và ký cơ sở PAdES là mã nguồn mở và đến được với mọi bề mặt; các
khả năng nâng cao được mở khóa bởi một phiên bản và khi đó có sẵn thông qua bất
kỳ bridge nào hoặc lối standalone một cách như nhau. Chọn một tích hợp framework
không phải là chọn một tập tính năng.
Hiểu lầm phản chiếu là “một engine” phải có nghĩa là một lối kết xuất duy nhất cho mọi tài liệu. Không phải vậy. Engine in-process kết xuất PDF trực tiếp; khi một tài liệu thực sự cần một engine bố cục cấp trình duyệt, một gói renderer xử lý việc đó. Kết xuất và lời gọi là hai trục riêng biệt — trang hướng dẫn quyết định tích hợp là nơi ánh xạ chúng.
Giới hạn và ranh giới
Phần tiêu đề “Giới hạn và ranh giới”Một bridge không mở rộng những gì engine có thể kết xuất. Đó là giới hạn trung thực, và nó chính là điểm mấu chốt: khả năng nằm ở phần lõi và phân hạng, không phải ở adapter mà bạn dùng để tiếp cận nó.
| Edition | Availability |
|---|---|
| Core | Mọi bridge (Laravel, Symfony, CodeIgniter) và lối standalone đều là Apache-2.0 và hoạt động trên Core. Chúng thích nghi hoặc phơi bày engine; chúng không gate tính năng và không thay đổi những gì engine có thể tạo ra. |
| Pro | Các khả năng nâng cao như xác thực chữ ký dài hạn (PAdES B-LT và B-LTA) được mở khóa bởi một phiên bản, rồi được tiếp cận giống hệt nhau qua bất kỳ bridge nào hoặc standalone — không bao giờ bằng cách đổi framework. Kết quả đầu ra PDF/A lưu trữ và ký cơ sở PAdES (B-B và B-T) đã có sẵn trong Core, có sẵn theo cùng một cách qua mọi bề mặt. |
| Enterprise | Hóa đơn điện tử có cấu trúc (EN 16931) và bộ công cụ tuân thủ sâu hơn cũng là các khả năng thuộc phiên bản, cũng giống hệt nhau bất kể bề mặt nào gọi engine, trong khi bản thân xác thực tuân thủ thì có sẵn trong Core. |
Có hai ranh giới nữa đáng nói thẳng. Thứ nhất, mỗi bridge bám theo một bản major hiện hành của framework của nó — Laravel, Symfony, và CodeIgniter mỗi cái ghim một dải phiên bản được hỗ trợ, nên “mọi framework” có nghĩa là phiên bản được hỗ trợ của từng cái, không phải mọi bản phát hành trong lịch sử; hãy coi tài liệu của chính mỗi gói là nguồn có thẩm quyền cho API của nó. Thứ hai, các bridge là adapter framework, không phải backend kết xuất. Nếu một tài liệu cần một engine bố cục trình duyệt đầy đủ, đó là một lựa chọn renderer độc lập với framework nào đã gọi engine.
Tài liệu liên quan
Phần tiêu đề “Tài liệu liên quan”- Hướng dẫn quyết định tích hợp — bản đồ ánh xạ trường-hợp-sử-dụng-sang-gói, bao gồm cả renderer và bề mặt service Connect, khi bạn cần quyết định thay vì chuẩn hóa.
- Open core, không khóa nhà cung cấp — vì sao engine là tài sản còn các bridge thì mỏng, nên việc chuẩn hóa không trói bạn lại.
- Pipeline HTML — những gì engine in-process bao trùm, để bạn biết khi nào một renderer trình duyệt là câu hỏi riêng biệt.
- Nền tảng PHP 8.4 — sàn runtime mà mọi bridge và lối standalone đều dùng chung.
Thuật ngữ
Phần tiêu đề “Thuật ngữ”- Engine lõi —
nextpdf/core, engine PDF 2.0 độc lập với framework mà mọi bridge và lối standalone đều xây dựng trên đó. - Bridge framework — một gói tích hợp (Laravel, Symfony, CodeIgniter) thích nghi engine với các idiom của một framework — facade, factory, response, queued job — mà không thay đổi các khả năng của nó.
- Lối standalone — dùng engine lõi trực tiếp, không có framework, bằng cách
tự dựng một
Document; lối đi cho các công cụ CLI, daemon, và thư viện. - Tài liệu dùng một lần — hợp đồng
Documentdùng-một-lần: dựng, phát ra, bỏ đi. Mỗi lần phân giải container trả về một cái tươi mới, nên không có trạng thái nào rò rỉ giữa các request trong một worker sống lâu. - PAdES — PDF Advanced Electronic Signatures, họ profile ETSI cho việc ký PDF. Ký cơ sở (B-B và B-T) có trong Core; xác thực dài hạn (B-LT và B-LTA) là một khả năng thuộc phiên bản nâng cao. Cái nào cũng được tiếp cận qua bất kỳ bề mặt nào, được trình bày sâu hơn trên các trang về ký.