Contracts / Document
Tổng quan nhanh
Phần tiêu đề “Tổng quan nhanh”Miền tài liệu chứa các contract dùng để tạo đầu ra Portable Document Format (PDF): PdfDocumentInterface cho nội dung, DocumentFactoryInterface để tạo tài liệu an toàn trong worker, các contract registry phông chữ và hình ảnh, cùng ba enum về đầu ra và bố cục. Tất cả đều stable kể từ 1.0.0 hoặc 1.7.0.
Cài đặt
Phần tiêu đề “Cài đặt”composer require nextpdf/core:^3Tổng quan khái niệm
Phần tiêu đề “Tổng quan khái niệm”PdfDocumentInterface là bề mặt giao diện lập trình ứng dụng (API) chính. Nó định nghĩa cách quản lý trang, chọn phông chữ, bố cục văn bản dạng ô và đa ô, kết xuất Hypertext Markup Language (HTML), nhúng hình ảnh và tạo đầu ra cuối cùng. Mỗi phương thức trả về static, nên bạn có thể nối chuỗi các lệnh gọi. Document::createStandalone() trả về một thực thể cụ thể thỏa mãn giao diện đó. Hãy khai báo kiểu theo giao diện này trong các dịch vụ của bạn để phần nội bộ của engine vẫn có thể được thay thế.
Việc tạo tài liệu có hai hướng. Trong một yêu cầu PHP FastCGI Process Manager (PHP-FPM) cổ điển, createStandalone() tạo một tài liệu khép kín với các registry riêng. Các worker chạy lâu, bao gồm RoadRunner, Swoole và Laravel Octane, dùng hướng còn lại. Trong mô hình đó, DocumentFactoryInterface::create() trả về một Document mới, chỉ dùng một lần. Tài liệu đọc từ các registry tồn tại trong suốt vòng đời tiến trình nhưng không bao giờ thay đổi chúng. Factory giữ các singleton FontRegistryInterface và ImageRegistryInterface. Mỗi tài liệu nhận một ngữ cảnh kết xuất và writer riêng. Cách này khoanh vùng lỗi: một tài liệu không thể làm hỏng trạng thái dùng chung mà tài liệu khác đang phụ thuộc.
Các contract registry giúp worker chạy nhanh. FontRegistryInterface phân tích một tệp phông chữ một lần và lưu cache siêu dữ liệu đã phân tích trong suốt vòng đời tiến trình. Bạn có thể khóa nó sau khi khởi động ấm để lưu lượng production không thể thay đổi registry. ImageRegistryInterface lưu cache dữ liệu nhị phân hình ảnh đã giải mã theo một chính sách least-recently-used có giới hạn. Siêu dữ liệu hình ảnh vẫn được giữ lại ngay cả sau khi phần nhị phân bị loại bỏ. Cả hai registry đều cung cấp memoryUsage() để lập kế hoạch dung lượng. ImageRegistryInterface mở rộng ResettableService, contract loại bỏ dữ liệu đã cache mà không hủy siêu dữ liệu cấu trúc. Một worker có thể xóa cache hình ảnh khi bộ nhớ chịu áp lực mà vẫn tiếp tục phục vụ.
Ba enum hoàn thiện miền này. OutputDestination chọn hiển thị nội tuyến, buộc tải xuống, ghi vào hệ thống tệp hoặc trả về chuỗi thô. Orientation chọn hướng dọc hoặc ngang. Alignment chọn văn bản căn trái, căn giữa, căn phải hoặc căn đều. Mỗi enum dùng mã TCPDF cũ làm giá trị enum, nên cầu nối compat-tcpdf ánh xạ gọn gàng. Cam kết tương thích ngược cho các enum này là chỉ bổ sung. Không case nào bị loại bỏ. Case mới có thể xuất hiện trong một bản phát hành minor.
Bề mặt API
Phần tiêu đề “Bề mặt API”| Kiểu | Loại | Thành viên chính | Độ ổn định | Từ phiên bản |
|---|---|---|---|---|
PdfDocumentInterface | interface | addPage(), setMargins(), setFont(), cell(), multiCell(), writeHtml(), image(), output(), save() | stable | 1.0.0 |
DocumentFactoryInterface | interface | create(?Config): Document | stable | 1.7.0 |
ResettableService | interface | reset(): void | stable | 1.7.0 |
FontRegistryInterface | interface | register(), get(), warmup(), lock(), isLocked(), registerFromBinary(), memoryUsage() | stable | 1.7.0 |
ImageRegistryInterface | interface | load(), loadFromString(), getMetadata(), memoryUsage() (mở rộng ResettableService) | stable | 2.0.0 |
OutputDestination | enum (string) | Inline, Download, File, String | stable | 1.0.0 |
Orientation | enum (string) | Portrait, Landscape | stable | 1.0.0 |
Alignment | enum (string) | Left, Center, Right, Justify | stable | 1.0.0 |
Trang typography ghi lại đầy đủ FontRegistryInterface và ImageRegistryInterface. Trang này tập trung vào vai trò của chúng trong vòng đời tạo tài liệu.
Mẫu mã — Bắt đầu nhanh
Phần tiêu đề “Mẫu mã — Bắt đầu nhanh”<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Hello World');$doc->addPage();$doc->setFont('helvetica', '', 24);$doc->cell(0, 15, 'Hello, NextPDF!', newLine: true);$doc->setFont('helvetica', '', 12);$doc->cell(0, 10, 'This is a minimal PDF generated with NextPDF.', newLine: true);$doc->save(__DIR__ . '/output/01-hello-world.pdf');Mẫu mã — Production
Phần tiêu đề “Mẫu mã — Production”<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\PdfFactory;use NextPDF\ValueObjects\{Margin, PageSize};
$factory = PdfFactory::new() ->withPageSize(PageSize::A4()) ->withMargins(new Margin(15.0, 15.0, 15.0, 15.0)) ->withCompress(true) ->withLang('en');
// The same configured factory creates independent documents.$doc = $factory->create();$doc->setTitle('PdfFactory Example');$doc->setAuthor('NextPDF');$doc->addPage();$doc->setFont('helvetica', '', 16);$doc->cell(0, 12, 'Created via PdfFactory', newLine: true);
$doc2 = $factory->create();$doc2->addPage();$doc2->setFont('helvetica', '', 12);$doc2->cell(0, 10, 'Second document from the same factory.');
$doc->save(__DIR__ . '/output/02-pdf-factory.pdf');PdfFactory là builder bất biến. Mỗi lệnh gọi with*() trả về một thực thể mới. Bên dưới, nó kết hợp một DocumentFactoryInterface, nên mô hình registry cho worker ở phần tổng quan được áp dụng mà không cần nối dây thêm.
Trường hợp biên & điều cần lưu ý
Phần tiêu đề “Trường hợp biên & điều cần lưu ý”createStandalone()tạo các registry riêng. Trong vòng lặp worker, điều đó sẽ phân tích lại mọi phông chữ ở mỗi yêu cầu. Thay vào đó, hãy dùngDocumentFactoryInterfacevới các registry dùng chung.- Một
Documentđược thiết kế để dùng một lần. Việc dùng lại cùng một thực thể cho nhiều tài liệu logic sẽ làm rò rỉ trạng thái. Hãy gọicreate()cho mỗi tài liệu và để bộ thu gom rác thu hồi nó. FontRegistryInterface::lock()khiếnregister(),addFontDirectory(), vàwarmup()ném raLogicException. Hãy khóa sau khi khởi động ấm, và đừng bao giờ khóa trong lúc xử lý yêu cầu.OutputDestination::Fileghi vào hệ thống tệp của máy chủ và trả về byte thô.save()là đường dẫn tệp tường minh. Đừng trộn lẫn cả hai cho cùng một tài liệu.cell()nhậnbool|stringcho đối số viền để tương thích với TCPDF. Chuỗi rỗng không giống vớifalse. Hãy truyền đúng giá trị có kiểu mà bạn muốn.
Hiệu năng
Phần tiêu đề “Hiệu năng”Các registry phông chữ và hình ảnh biến miền tài liệu thành một hệ thống bị giới hạn bởi bộ nhớ, thay vì theo từng yêu cầu. Việc phân tích phông chữ ở yêu cầu đầu tiên chiếm phần lớn thời gian. performance_budget là 1.500 ms wall và 64 MB đỉnh trên ba tài liệu trong ví dụ worker. Gần như toàn bộ ngân sách đó dành cho lần phân tích phông chữ đầu tiên. Sau khi khởi động ấm, phần việc mà contract gây ra trên mỗi tài liệu là O(1): một lần tra registry và một lần cấp phát ngữ cảnh. memoryUsage() trên một trong hai registry trả về một MemoryReport để lập kế hoạch dung lượng trực tiếp. ResettableService::reset() giới hạn bộ nhớ đỉnh khi tải kéo dài.
Lưu ý bảo mật
Phần tiêu đề “Lưu ý bảo mật”Các contract tài liệu không có bề mặt mật mã, nhưng có hai rủi ro vận hành cần lưu ý. Thứ nhất, image() nhận một đường dẫn hoặc Uniform Resource Locator (URL). Trong các tình huống đầu vào không đáng tin, hãy ràng buộc việc tải từ xa qua ExternalResourcePolicyInterface (xem trang security-policy) thay vì truyền trực tiếp các URL do người dùng kiểm soát. Thứ hai, writeHtml() là điểm vào cho pipeline HTML. Mã đánh dấu không đáng tin phải đi qua một HtmlSecurityPolicyInterface trước khi kết xuất. Lớp tài liệu tự nó không làm sạch dữ liệu. Đó là trách nhiệm của miền security-policy, và vì đây là một contract, bạn có thể cung cấp một chính sách nghiêm ngặt hơn mà không cần fork.
Tuân thủ
Phần tiêu đề “Tuân thủ”Các contract tài liệu hiện thực cấu trúc tài liệu PDF 2.0 như được định nghĩa trong ISO 32000-2. Việc xử lý đầu ra, trang và phông chữ tạo ra các đối tượng gián tiếp và một luồng tham chiếu chéo theo ISO 32000-2 §7. Lớp writer phát ra nội dung theo contract của lớp engine, được ghi lại trong bản ghi quyết định kiến trúc (ADR-010). Trang này không khẳng định bất kỳ tuyên bố ở cấp điều khoản nào ngoài việc tuân thủ về cấu trúc. Các trang trích xuất và trợ năng ghi lại việc tuân thủ PDF/A và PDF/UA, đồng thời mang theo các bảng quy chuẩn.
Xem thêm
Phần tiêu đề “Xem thêm”- Contracts: 41 giao diện công khai (SPI) — tổng quan về giao diện nhà cung cấp dịch vụ (SPI) và các bậc độ ổn định.
- Contracts / Typography — tài liệu đầy đủ cho
FontRegistryInterface. - Contracts / Security Policy — các chính sách kiểm soát
writeHtml()vàimage(). - Core — các lớp cụ thể
DocumentvàPdfFactory. - Document — mô-đun dựng tài liệu.
- Writer — lớp phát ra các đối tượng PDF cho các contract này.