Contracts / trích xuất
Tổng quan nhanh
Phần tiêu đề “Tổng quan nhanh”Miền trích xuất định nghĩa các contract dùng để đọc và kiểm tra các tệp Portable Document Format (PDF), rồi chuyển nội dung của chúng thành dữ liệu có cấu trúc. Miền này bao gồm inspector, trình kiểm tra tuân thủ, trình quản lý PDF/A, các contract cho đối tượng đã nhập, contract embedding và chỉ mục vector, cùng sub-namespace của trình kiểm tra hóa đơn điện tử.
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”InspectorInterface đọc các byte PDF thô và trả về một InspectResult có cấu trúc. Kết quả liệt kê các đối tượng trong tệp. Hãy dùng contract này cho bất kỳ công cụ nào đọc một PDF mà engine không tạo ra.
ExternalComplianceValidatorInterface kết nối engine với một trình kiểm tra bên ngoài như veraPDF. Trình kiểm tra này kiểm tra PDF/A và PDF/Universal Accessibility (PDF/UA). Khi chưa cấu hình trình kiểm tra nào, bản triển khai null trả về kết quả “không khả dụng”. Một site không có veraPDF vẫn chạy được. ProfileValidatorInterface kiểm tra runtime so với một profile triển khai, bao gồm các extension bắt buộc và được khuyến nghị. Nó trả về một kết luận có kiểu.
PdfAManagerInterface giữ cho tệp PDF/A đúng spec trong khi writer dựng tệp đó. Nó chặn JavaScript, các form action JavaScript và mã hóa tích hợp sẵn. PDF/A cấm cả ba thứ này. Nó cũng kiểm tra để bảo đảm mọi phông chữ đều được nhúng, đặt metadata đúng spec và ghi các đối tượng cần thiết trước catalog. Class thực sự được phát hành trong phiên bản Pro. Core tìm thấy class này bằng class_exists() và ép kiểu nó về contract. Engine mã nguồn mở không có dependency trả phí nào.
Hai contract bao quát các đối tượng đã nhập: ImportedFormObjectInterface và EmbeddedPdfObjectInterface. Chúng cung cấp quyền truy cập có kiểu vào các đối tượng đọc từ một PDF có sẵn để engine có thể nhúng lại chúng. Đường dẫn không mất dữ liệu giữ nguyên các byte dictionary thô. Đường dẫn dự phòng cung cấp một mảng dictionary đã phân tích cú pháp cho các đối tượng lấy từ object stream. Mỗi đối tượng được nhúng lại là một indirect object của PDF. Object number và generation number nhận diện đối tượng này, như được định nghĩa trong ISO 32000-2 §7.3.10.
Các contract embedding hỗ trợ tìm kiếm. EmbeddingServiceInterface chuyển văn bản thành một vector đặc, đồng thời báo cáo kích thước và tên mô hình để bên gọi có thể thích ứng tại runtime. Phiên bản Pro chạy một mô hình central processing unit (CPU). Phiên bản Enterprise chạy một mô hình graphics processing unit (GPU). VectorIndexInterface dựng và tìm kiếm trong một chỉ mục nearest-neighbor. Đây là chỉ mục in-process nhỏ dành cho core. Tìm kiếm ở quy mô lớn hơn nằm trong một contract chỉ có ở Enterprise.
Nhóm EInvoice chứa trình kiểm tra hóa đơn điện tử dùng chung cho mọi cấp. ValidatorInterface chạy các kiểm tra sơ bộ trên payload Cross Industry Invoice (CII) hoặc Universal Business Language (UBL). SchematronRunnerInterface chạy lượt kiểm tra theo quy tắc nghiệp vụ. ValidationResult thu thập các phát hiện và vi phạm quy tắc. Trình kiểm tra phải từ chối đầu vào sai bằng một kết quả, chứ không phải bằng exception. Nó cũng phải đề phòng các payload có Document Type Declaration (DOCTYPE) và payload quá lớn.
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 |
|---|---|---|---|---|
InspectorInterface | interface | inspect(string, InspectConfig): InspectResult | thử nghiệm | 2.2.0 |
ExternalComplianceValidatorInterface | interface | validate(string, ComplianceFlavour), isAvailable() | thử nghiệm | 2.4.0 |
ProfileValidatorInterface | interface | validate(DeploymentProfile): DeploymentProfileResult | thử nghiệm | 2.4.0 |
PdfAManagerInterface | interface | validateNoJavaScript(), validateFont(), validateNoEncryption(), applyOutputProfile(), writeRequiredObjects() | ổn định | 1.10.0 |
ImportedFormObjectInterface | interface | getWidth(), getHeight(), getEmbeddedObjects(), getResourcesDict(), getMediaBox(), getContentStream() | ổn định | 1.8.0 |
EmbeddedPdfObjectInterface | interface | getRawDictionaryBytes(), getRawStreamData(), getDictionary() | ổn định | 1.8.0 |
EmbeddingServiceInterface | interface | embed(), batchEmbed(), getDimension(), getModelName() | thử nghiệm | 2.1.0 |
VectorIndexInterface | interface | build(), search(), delete(), count() | thử nghiệm | 2.1.0 |
EInvoice\ValidatorInterface | interface | validate(string, ValidatorContext): ValidationResult | thử nghiệm | 5.1.0 |
EInvoice\ValidationResult | final readonly class | $isValid, getErrors(), getWarnings(), fail() | thử nghiệm | 5.1.0 |
Namespace EInvoice cũng công bố SchematronRunnerInterface, ProfileInterface, ValidationFinding, RuleViolation, cùng các enum ProfileType, RuleSeverity và ValidationFindingLevel.
Ví dụ mã — bắt đầu nhanh
Phần tiêu đề “Ví dụ mã — bắt đầu nhanh”<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\InspectorInterface;use NextPDF\Inspect\InspectConfig;
/** * Inspect a PDF and report its object count. * * @param InspectorInterface $inspector A configured inspector. * @param string $pdfData Raw PDF bytes. */function describe(InspectorInterface $inspector, string $pdfData): \NextPDF\Inspect\InspectResult{ return $inspector->inspect($pdfData, new InspectConfig());}Hàm phụ thuộc vào contract. Bất kỳ bản triển khai inspector nào cũng có thể đáp ứng contract đó.
Ví dụ mã — môi trường sản xuất
Phần tiêu đề “Ví dụ mã — môi trường sản xuất”<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\EInvoice\ValidatorInterface;use NextPDF\Contracts\EInvoice\ValidatorContext;use NextPDF\Contracts\ExternalComplianceValidatorInterface;use NextPDF\ValueObjects\ComplianceFlavour;use Psr\Log\LoggerInterface;
final readonly class InvoiceConformanceService{ public function __construct( private ValidatorInterface $invoiceValidator, private ExternalComplianceValidatorInterface $pdfaValidator, private LoggerInterface $logger, ) {}
/** * Validate the invoice XML, then the PDF/A-3 carrier. * * @param string $xml The CII or UBL invoice payload. * @param string $pdfPath Absolute path to the PDF/A-3 carrier. */ public function validate(string $xml, string $pdfPath, ValidatorContext $ctx): bool { $result = $this->invoiceValidator->validate($xml, $ctx);
if (!$result->isValid) { $this->logger->warning('Invoice XML invalid', [ 'errors' => \count($result->getErrors()), ]);
return false; }
if (!$this->pdfaValidator->isAvailable()) { $this->logger->info('PDF/A validator unavailable; skipping carrier check.');
return true; }
$carrier = $this->pdfaValidator->validate($pdfPath, ComplianceFlavour::PdfA3b);
return $carrier->isConformant(); }}Service xử lý rõ ràng trường hợp không có validator, thay vì giả định rằng validator đã tồn tại.
Trường hợp biên và lưu ý dễ vấp
Phần tiêu đề “Trường hợp biên và lưu ý dễ vấp”EInvoice\ValidatorInterface::validate()trả về mộtValidationResultthất bại khi đầu vào không hợp lệ. Nó không ném exception cho các vi phạm về tính đúng định dạng. Hãy kiểm tra$isValid; đừng bọc lời gọi trong một try/catch cho trường hợp đó.ExternalComplianceValidatorInterface::isAvailable()phải được kiểm tra trước khi bạn dựa vào một kết luận. Bản triển khai null trả về “không khả dụng”. Coi giá trị đó là “không tuân thủ” sẽ tạo ra kết quả âm tính giả.EmbeddedPdfObjectInterface::getRawDictionaryBytes()trả vềnullđối với các đối tượng lấy từ object stream. Hãy chuyển sang dùnggetDictionary(). Đừng giả định rằng các byte thô luôn tồn tại.EmbeddingServiceInterface::getDimension()khác nhau tùy theo từng cấp. Mã cấp phát vector có độ rộng cố định phải đọc số chiều tại runtime, không gán cứng số chiều.VectorIndexInterface::build()yêu cầu danh sách vector và danh sách id có độ dài bằng nhau, đồng thời có số chiều nhất quán. Nếu không khớp, lệnh sẽ phát sinhInvalidArgumentException. Hãy kiểm tra các danh sách trước khi dựng chỉ mục.
Hiệu năng
Phần tiêu đề “Hiệu năng”Chi phí kiểm tra và xác thực tỉ lệ với kích thước tài liệu và số lượng đối tượng. performance_budget là 1500 ms thời gian thực và 64 MB đỉnh, đủ cho một tài liệu cỡ trung bình. Một lời gọi veraPDF bên ngoài sẽ tự thêm thời gian xử lý riêng. Thời gian đó nằm ngoài ngân sách của engine và nên chạy bên ngoài đường xử lý request. Chi phí embedding tỉ lệ với độ dài văn bản và rẻ hơn nhiều khi xử lý theo lô thay vì trong một vòng lặp, đặc biệt là trên mô hình GPU. Hãy ưu tiên dùng batchEmbed(). Với chỉ mục in-process, tìm kiếm vector có độ phức tạp dưới tuyến tính theo kích thước chỉ mục. Profile khả năng tái lập là structural. Báo cáo kiểm tra ghi lại dấu thời gian và fingerprint môi trường. Hai lần chạy có thể khác nhau ở các trường đó, trong khi kết luận tuân thủ vẫn giống hệt nhau.
Lưu ý bảo mật
Phần tiêu đề “Lưu ý bảo mật”Quá trình trích xuất đọc các tài liệu mà engine không tạo ra, vì vậy mọi đầu vào đều không đáng tin cậy. Cả inspector và trình kiểm tra hóa đơn điện tử đều phân tích cú pháp các byte được cung cấp từ bên ngoài. Trình kiểm tra hóa đơn điện tử phải chặn các payload có Document Type Declaration (DOCTYPE), payload quá lớn và payload chứa ký tự điều khiển bị cấm trước khi phân tích cú pháp, nhằm ngăn các tấn công external-entity và billion-laughs của Extensible Markup Language (XML). Việc nhúng lại đối tượng đã nhập sao chép các byte từ một PDF bên ngoài. Một đối tượng nguồn độc hại có thể mang nội dung gây hại, nên việc nhúng lại giữ nguyên các byte mà không thực thi chúng. Việc cưỡng chế PDF/A loại bỏ JavaScript và các action. Trình quản lý PDF/A từ chối JavaScript và mã hóa vì cả hai đều bị cấm trong profile, đồng thời đều là vector lạm dụng trong tài liệu lưu trữ dài hạn. Hãy luôn coi nội dung đã kiểm tra, các đối tượng đã nhập và XML hóa đơn là đầu vào gây hại.
Tuân thủ
Phần tiêu đề “Tuân thủ”| Tuyên bố | Tiêu chuẩn | Điều khoản | Bằng chứng |
|---|---|---|---|
| PDF/A-4 cấm JavaScript và các form action JavaScript; trình quản lý PDF/A từ chối cả hai. | ISO 19005-4 | §6.7.1 | trích dẫn theo điều khoản (không có trong corpus) |
| Mỗi đối tượng được nhúng lại là một indirect object của PDF, được nhận diện bằng object number và generation. | ISO 32000-2 | §7.3.10 |
ISO 19005-4 được trích dẫn theo điều khoản. Tiêu chuẩn này không có trong corpus trích dẫn có thể xác minh, nên không ghi lại reference_id nào. Tuyên bố về indirect object của ISO 32000-2 được neo theo bảng thuật ngữ. Cả hai tuyên bố đều được diễn giải lại. Engine không tái tạo bất kỳ văn bản quy phạm nào.
Bối cảnh thương mại
Phần tiêu đề “Bối cảnh thương mại”Core định nghĩa và đóng băng các contract trích xuất. Mã sản xuất phía sau PdfAManagerInterface, EmbeddingServiceInterface và VectorIndexInterface được phát hành trong các phiên bản Pro và Enterprise, bao gồm các mô hình embedding CPU và GPU cùng toàn bộ đường cưỡng chế PDF/A. Core phân giải các thành phần này tại runtime bằng class_exists(). Do đó, engine mã nguồn mở không mang theo dependency thương mại nào, và application programming interface (API) không thay đổi khi nâng cấp.
Xem thêm
Phần tiêu đề “Xem thêm”- Contracts: 41 public interface — tổng quan về Service Provider Interface (SPI) và các cấp độ ổn định.
- Contracts / Document — các contract tài liệu tạo vật mang PDF/A.
- Contracts / Signing — lưu trữ đã ký, kết hợp cùng việc cưỡng chế PDF/A.
- Inspect — bản cài đặt inspector phía sau
InspectorInterface. - Text — trích xuất văn bản sử dụng các đối tượng đã kiểm tra.
- Metadata — metadata PDF/A do trình quản lý cấu hình.