Bỏ qua để đến nội dung

Contracts: 41 giao diện công khai (SPI)

NextPDF\Contracts là giao diện nhà cung cấp dịch vụ (SPI) công khai: 41 giao diện và enum nằm trong src/Contracts/, mỗi kiểu có một thẻ @stability rõ ràng và một cam kết tương thích ngược. Các gói mở rộng, cầu nối framework, cũng như phiên bản Pro và Enterprise phụ thuộc vào những kiểu này, không bao giờ phụ thuộc vào lớp cụ thể.

Terminal window
composer require nextpdf/core:^3

Engine cung cấp hai bề mặt. Các lớp cụ thể nằm trong src/Core/, src/Html/src/Writer/ không có cam kết tương thích và có thể thay đổi giữa các phiên bản minor. Không gian tên Contracts thì khác. Đây là một tập hợp kiểu được tuyển chọn, với chữ ký được đóng băng theo bậc ổn định mà chúng khai báo. Mọi thứ bên ngoài engine đều phụ thuộc vào không gian tên này, và không đi sâu hơn. Điều đó bao gồm các cầu nối Laravel, Symfony và CodeIgniter, lớp đệm compat-tcpdf, NextPDF Server, cùng phiên bản Pro và Enterprise.

Mỗi contract khai báo một trong bốn bậc trong PHPDoc của nó. Một contract stable không cho phép thay đổi gây phá vỡ trong bản phát hành minor hoặc patch. Phương thức mới chỉ xuất hiện khi có cài đặt mặc định đi kèm. Một contract experimental có thể thay đổi trong một bản phát hành minor kèm thông báo loại bỏ. Một contract deprecated nêu rõ phần thay thế cho nó. Một số ít chỉ là contract, chẳng hạn StreamingWriterInterfaceCursorInterface. Các kiểu này được công bố và đóng băng, nhưng chưa có cài đặt dùng cho sản xuất đi kèm.

Danh sách bậc chính thức là docs/extension-points.json (manifest phiên bản 3.0.0, 67 điểm được công bố trên ContractsEvent). Một bài kiểm thử có thể xác minh bằng máy, tests/Unit/Contracts/StabilityContractTest.php, đọc manifest đó và làm hỏng quá trình build trong năm trường hợp. Thứ nhất, một kiểu được liệt kê bị thiếu. Thứ hai, loại được phản chiếu (reflected kind) không khớp với manifest. Thứ ba, một thẻ PHPDoc @stability lệch khỏi manifest. Thứ tư, một contract nằm trong src/Contracts/ nhưng vắng mặt trong manifest. Thứ năm, một kiểu @internal lọt vào đó. Bề mặt contract không thể lệch khỏi khai báo mà không bị phát hiện.

Các contract được chia thành chín lĩnh vực, mỗi lĩnh vực có một trang riêng: tạo tài liệu, ký, mã hóa mã vạch, kiểu chữ, chính sách bảo mật, trích xuất, khả năng quan sát và streaming. Cách chia này phản ánh cách bạn sử dụng engine. Bạn phụ thuộc vào contract document để tạo tệp Portable Document Format (PDF). Bạn phụ thuộc vào các contract ký để thêm chữ ký. Bạn phụ thuộc vào các contract chính sách bảo mật để giới hạn HTML không tin cậy.

Việc phân giải cài đặt tùy chọn tuân theo một mẫu chung trên toàn engine. Core kiểm tra một lớp cụ thể bằng class_exists() rồi ép kiểu lớp đó về contract. LtvManagerInterfacePdfAManagerInterface phân giải cài đặt Pro của chúng theo cách này. Core vẫn giữ giấy phép Apache-2.0 mà không có phụ thuộc cứng vào mã thương mại.

ContractLoạiMức độ ổn địnhTừ phiên bảnLĩnh vực
PdfDocumentInterfaceinterfacestable1.0.0document
DocumentFactoryInterfaceinterfacestable1.7.0document
ResettableServiceinterfacestable1.7.0document
OutputDestinationenumstable1.0.0document
Orientationenumstable1.0.0document
Alignmentenumstable1.0.0document
SignerInterfaceinterfacestable1.0.0signing
HsmSignerInterfaceinterfacestable1.0.0signing
DeferredSignerInterfaceinterfaceexperimental3.0.0signing
TimestampProviderInterfaceinterfaceexperimental3.0.0signing
LtvManagerInterfaceinterfacestable1.10.0signing
CryptoPolicyInterfaceinterfacestable1.9.0signing
Barcode1DEncoderInterfaceinterfacestable1.0.0barcode
Barcode2DEncoderInterfaceinterfacestable1.0.0barcode
BarcodeEncoderInterfaceinterfacestable3.0.0barcode
Gs1DataParserInterfaceinterfacestable1.0.0barcode
FontRegistryInterfaceinterfacestable1.7.0typography
TextPreprocessorInterfaceinterfacestable1.9.0typography
HtmlSecurityPolicyInterfaceinterfacestable3.1.0security-policy
ExternalResourcePolicyInterfaceinterfacestable4.0.0security-policy
InspectorInterfaceinterfaceexperimental2.2.0extraction
EmbeddingServiceInterfaceinterfaceexperimental2.1.0extraction
VectorIndexInterfaceinterfaceexperimental2.1.0extraction
JobNotificationInterfaceinterfaceexperimental2.2.0observability
SpectrumInterfaceinterfaceexperimental2.1.0observability
StreamingWriterInterfaceinterfaceexperimental3.1.0streaming
CursorInterfaceinterfaceexperimental3.1.0streaming

Bảng này liệt kê các contract chính. Các kiểu còn lại, bao gồm các đối tượng truyền dữ liệu value-object (DTO) (TextSegment, TextPreprocessResult), không gian tên con EInvoice, các enum hành vi (DegradationPolicy, UnderlineStyle), và các contract import (ImportedFormObjectInterface, EmbeddedPdfObjectInterface, ChromeRenderResultInterface), được ghi tài liệu trên các trang lĩnh vực trong mục Xem thêm. Danh sách đầy đủ có thể đọc bằng máy là docs/extension-points.json, được sao chép sang .ai/contracts-map.md.

examples/01-hello-world.php
<?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->save(__DIR__ . '/output/01-hello-world.pdf');

Document::createStandalone() trả về một Document cụ thể thỏa mãn PdfDocumentInterface. Hãy khai báo kiểu (type-hint) bằng interface trong các service của bạn để phần nội bộ của engine luôn có thể hoán đổi được.

examples/14-worker-factory.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\DocumentFactory;
use NextPDF\Core\PdfFactory;
use NextPDF\Graphics\ImageRegistry;
use NextPDF\Typography\FontRegistry;
// Created once at process boot in a RoadRunner/Swoole/Octane worker.
$fontRegistry = new FontRegistry();
$imageRegistry = new ImageRegistry(maxCacheBytes: 50 * 1024 * 1024);
$documentFactory = new DocumentFactory($fontRegistry, $imageRegistry);
$factory = PdfFactory::new()
->withCompress(true)
->withDocumentFactory($documentFactory);
for ($request = 1; $request <= 3; $request++) {
$doc = $factory->create();
$doc->setTitle("Worker Request #{$request}");
$doc->addPage();
$doc->setFont('helvetica', 'B', 16);
$doc->cell(0, 12, "Worker Request #{$request}", newLine: true);
$doc->save(__DIR__ . "/output/14-worker-request-{$request}.pdf");
}

DocumentFactory hiện thực DocumentFactoryInterface. Nó giữ các singleton FontRegistryInterfaceImageRegistryInterface trong suốt vòng đời tiến trình rồi tiêm chúng vào từng Document dùng một lần, nhờ vậy một worker chỉ phân tích mỗi phông chữ một lần qua hàng nghìn yêu cầu.

Trường hợp đặc biệt & điểm cần lưu ý

Phần tiêu đề “Trường hợp đặc biệt & điểm cần lưu ý”
  • Một kiểu chỉ là contract có thể biên dịch được nhưng không có phần hỗ trợ lúc chạy. Một biểu thức new đối với StreamingWriterInterface hoặc CursorInterface không thể thành công vì chưa có lớp nào hiện thực chúng. Hãy coi chúng như một giao diện lập trình ứng dụng (API) được khai báo trước.
  • Thẻ PHPDoc @stability là nguồn xác thực cho một kiểu đơn lẻ. docs/extension-points.json là nguồn xác thực cho cả tập hợp. Khi chúng không khớp, StabilityContractTest sẽ thất bại. Đừng che giấu sự không khớp bằng cách chỉnh sửa một bên.
  • experimental trên thực tế không có nghĩa là không ổn định. Nó nghĩa là cam kết tương thích yếu hơn. Hãy đọc trường bc_promise của mỗi contract trong .ai/contracts-map.md trước khi ghim vào nó.
  • Một lớp @internal không bao giờ là contract, ngay cả khi các gói khác về mặt kỹ thuật có thể tham chiếu đến nó. Bài kiểm thử ổn định từ chối mọi kiểu @internal xuất hiện trong manifest.
  • Thêm một phương thức vào interface stable là một thay đổi gây phá vỡ đối với bên hiện thực, trừ khi phương thức đó có cài đặt mặc định đi kèm. Engine bổ sung khả năng thông qua các interface mới, chứ không phải bằng cách mở rộng những interface hiện có.

Lập trình dựa trên Contracts không thêm chi phí lúc chạy nào đo lường được: việc khai báo kiểu bằng interface được phân giải tại thời điểm liên kết, chứ không phải ở mỗi lần gọi. performance_budget cho ví dụ worker của trang này là 1500 ms thời gian thực và 64 MB đỉnh trên ba tài liệu. Việc phân tích phông chữ ở yêu cầu đầu tiên chiếm phần lớn ngân sách đó. Các yêu cầu sau dùng lại cache của registry và giảm xuống còn vài mili-giây một chữ số cho phần việc do contract gây ra. Mô hình chi phí là O(1) cho mỗi lần điều phối contract; phần việc nằm trong cài đặt cụ thể, được ghi tài liệu trên từng trang lĩnh vực.

SPI cũng là một ranh giới bảo mật. HtmlSecurityPolicyInterfaceExternalResourcePolicyInterface là các contract mặc-định-từ-chối, giới hạn những gì HTML không tin cậy có thể làm trước khi nó đến bộ kết xuất. CryptoPolicyInterface kiểm soát việc lựa chọn thuật toán và độ mạnh khóa cho việc ký và mã hóa. Vì đây là các 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 engine. Hãy ghim vào bậc stable cho bất kỳ chính sách nào liên quan đến bảo mật. Các contract chính sách thử nghiệm có thể thay đổi hình dạng giữa các bản phát hành minor. Các trang lĩnh vực ký và chính sách bảo mật chứa mô hình mối đe dọa đầy đủ cùng các tham chiếu quy chuẩn.

Bản tổng quan này không đưa ra tuyên bố quy chuẩn trực tiếp nào; mỗi trang lĩnh vực kết xuất khối citations riêng của nó. Các contract ký ánh xạ sang ISO 32000-2 §12.8 (chữ ký số) và ETSI EN 319 142 (các baseline PAdES). Trình quản lý PDF/A ánh xạ sang ISO 19005-4. Hãy xem các trang ký, chính sách bảo mật và trích xuất để biết các bảng tuân thủ ở cấp điều khoản.

Phiên bản Pro và Enterprise cung cấp mã dùng cho sản xuất phía sau một số contract core: LtvManagerInterface (xác thực dài hạn), PdfAManagerInterface (thực thi PDF/A), Mô-đun Bảo mật Phần cứng (HSM) và các bộ ký trì hoãn, các bộ mã hóa mã vạch, cùng các contract embedding và vector-index. Core công bố và đóng băng interface; gói Premium cung cấp phần cài đặt. Điều này giúp engine mã nguồn mở giữ giấy phép Apache-2.0 và mang lại cho các triển khai thương mại một bản nâng cấp có thể gắn trực tiếp vào mà không thay đổi API.

  • Contracts / Document — các contract document PDF, factory và registry.
  • Contracts / Signing — các contract signer, HSM, timestamp và xác thực dài hạn (LTV).
  • Contracts / Security Policy — các contract chính sách crypto, HTML và tài nguyên.
  • Contracts / Typography — các contract registry phông chữ và tiền xử lý văn bản.
  • Contracts / Extraction — các contract inspector, PDF/A, embedding và hóa đơn điện tử.
  • Core — các lớp cụ thể thỏa mãn các contract này.
  • Event — SPI sự kiện đồng hành được công bố cùng với Contracts.