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

Hướng dẫn dành cho nhà phát triển Artisan

Gói Artisan đảm nhận hai trách nhiệm gắn kết với nhau: kết xuất Hypertext Markup Language (HTML) bằng Chrome và nhập trang Portable Document Format (PDF) thu được vào tài liệu NextPDF. Khi gỡ lỗi sự cố, hãy tách bạch các ranh giới Chrome, bộ phân tích cú pháp và bộ nhập.

Hãy dùng hướng dẫn này khi viết các tích hợp bộ kết xuất, các worker chạy lâu, chẩn đoán bộ phân tích cú pháp hoặc kiểm thử cho nextpdf/artisan.

LớpThuộc vềTrách nhiệmKhông đặt ở đây
Ứng dụngỨng dụngCấp quyền tạo HTML và chọn cấu hình bộ kết xuất.Quản lý tiến trình trình duyệt.
Chính sách HTMLỨng dụng và góiTừ chối HTML không an toàn hoặc quá lớn trước khi kết xuất.Cấp quyền cho tenant hoặc quyết định nghiệp vụ.
Bộ kết xuất Chromenextpdf/artisanKết xuất HTML thành một PDF độc lập do Chrome tạo.Sửa chữa PDF chung hoặc chỉnh sửa PDF tùy ý.
Bộ phân tích cú pháp/bộ nhậpnextpdf/artisanPhân tích cú pháp PDF đã kết xuất và nhập một trang dưới dạng form XObject.Xác thực tuân thủ PDF đầy đủ.
Engine lõinextpdf/nextpdfĐặt các đối tượng form đã nhập và ghi tài liệu sau cùng.Vòng đời Chrome DevTools Protocol (CDP).
Giai đoạnHành viHành động của nhà phát triển
Tạo cấu hìnhChromeRendererConfig xác định binary, thời gian chờ, Cascading Style Sheets (CSS), kích thước đầu vào và hành vi sandbox.Dùng cấu hình riêng cho từng môi trường thay vì hard-code các giá trị suy đoán khi chạy.
Tạo bộ kết xuấtChromeHtmlRenderer sở hữu một BrowserPool.Tái sử dụng bộ kết xuất trong một worker, rồi đóng nó khi tắt.
Xác thực HTMLChính sách bảo mật kiểm tra kích thước và bọc tài liệu bằng CSS mặc định.Xác thực quyền của người gọi trước giai đoạn này.
In bằng ChromeCDP kết xuất một PDF độc lập.Tiếp tục chặn các tài nguyên bên ngoài, trừ khi một chính sách đã được rà soát cho phép chúng.
Phân tích cú pháp PDFPdfReader::parse() đọc dữ liệu xref, các trang, đối tượng, tài nguyên và các bản sửa đổi.Hãy coi lỗi của bộ phân tích cú pháp là lỗi kết xuất, trừ khi mục tiêu là chẩn đoán.
Nhập trangPageImporter::import() trích xuất nội dung trang, media box, tài nguyên và các đối tượng nhúng.Nhập trang 0 trừ khi quy trình cố ý chọn một trang khác.
Đường dẫnMục đích
app/Pdf/Renderers/*Lớp bao ứng dụng quanh ChromeHtmlRenderer.
app/Pdf/Templates/*Kết xuất mẫu HTML và ánh xạ data transfer object (DTO) sang view.
app/Pdf/Policies/*Chính sách kết xuất về kích thước HTML, tài nguyên và tenant.
tests/Pdf/Renderer/*Kiểm thử smoke cho bộ kết xuất với các fixture HTML nhỏ.
tests/Pdf/Parser/*Các fixture phân tích cú pháp cho đầu ra Chrome đã nhập.

Hãy tách biệt việc kết xuất mẫu với việc kết xuất bằng trình duyệt. Truyền HTML cuối cùng và chiều rộng trang đã biết cho bộ kết xuất.

<?php
use NextPDF\Artisan\ChromeHtmlRenderer;
use NextPDF\Artisan\ChromeRendererConfig;
use NextPDF\Artisan\PageImporter;
use NextPDF\Parser\PdfReader;
$renderer = new ChromeHtmlRenderer(new ChromeRendererConfig(
renderTimeout: 30,
maxHtmlSize: 1_000_000,
));
$result = $renderer->render($html, widthPt: 595.28);
$reader = new PdfReader($result->getPdfData());
$reader->parse();
$form = (new PageImporter())->import($reader);

Tạo một bộ kết xuất cho mỗi tiến trình worker hoặc mỗi phạm vi yêu cầu. Tái sử dụng nó để tránh lặp lại chi phí khởi động Chrome. Đóng nó một cách tường minh để ngăn rò rỉ tiến trình khi worker tắt.

<?php
final class InvoiceChromeRenderer
{
public function __construct(
private readonly ChromeHtmlRenderer $renderer,
) {}
public function renderInvoice(string $html): string
{
return $this->renderer
->render($html, widthPt: 595.28)
->getPdfData();
}
public function close(): void
{
$this->renderer->close();
}
}

Hãy dùng các application programming interface (API) của bộ phân tích cú pháp khi không thể nhập đầu ra Chrome. Giữ chẩn đoán ở chế độ chỉ đọc và tránh thay đổi trạng thái của bộ phân tích cú pháp sau khi nhập thành công.

Câu hỏi chẩn đoánAPI cần dùngTín hiệu mong đợi
Tệp có được phân tích cú pháp không?PdfReader::parse()Ném ngoại lệ khi cấu trúc PDF không hợp lệ.
Trang 0 có tồn tại không?PdfReader::getPage(0)Trả về một PdfObject.
Có nội dung không?PdfReader::getPageContentStream($page)Luồng nội dung không rỗng.
Tài nguyên có hiện diện không?PdfReader::getPageResources($page)Mảng từ điển tài nguyên.
Có các bản sửa đổi tăng dần không?PdfReader::getRevisionCount()Số lượng lớn hơn một.
Đối tượng nào bị lỗi?PdfTokenizer::getOffset() và ngữ cảnh ngoại lệ của bộ phân tích cú pháp.Vị trí byte offset để rút gọn fixture.
Điểm mở rộngDùng choRàng buộc
ChromeRendererConfig::fromArray()Ánh xạ cấu hình framework.Các giá trị tùy chọn không xác định hoặc sai kiểu sẽ quay về giá trị mặc định.
HtmlSecurityPolicyInterfaceChính sách HTML ở lớp phân tích cú pháp.Không thay thế các kiểm soát về truyền tải, tiến trình hoặc cấp quyền.
LoggerInterfaceChẩn đoán kết xuất và trình duyệt.Không ghi nhật ký nội dung HTML theo mặc định.
BrowserPoolTái sử dụng tiến trình Chrome tồn tại lâu.Phải được đóng khi worker tắt.
PageImporterNhúng một trang bên ngoài đã được phân tích cú pháp.Reader phải được phân tích cú pháp trước.
Các lớp của bộ phân tích cú phápChẩn đoán và đầu ra Chrome đã nhập.Không phải là bộ công cụ sửa chữa PDF chung.
  1. Tái hiện đoạn HTML trong một bài kiểm thử kết xuất tối thiểu.
  2. Xác thực maxHtmlSize, CSS mặc định và đường dẫn binary của Chrome.
  3. Kết xuất với chiều rộng cố định tính bằng điểm.
  4. Phân tích cú pháp các byte PDF được trả về bằng PdfReader::parse().
  5. Nhập trang 0 trừ khi quy trình cố ý chọn một trang khác.
  6. Thêm các bài kiểm thử fixture cho đoạn HTML nhỏ nhất tái hiện được từng lỗi.
  7. Đóng bộ kết xuất trong các hook tắt worker.
LỗiNơi cần xử lýPhản hồi được khuyến nghị
Thiếu binary của ChromeKiểm tra khi triển khai và đường dẫn khởi tạo bộ kết xuất.Báo trạng thái chưa sẵn sàng trước khi tiếp nhận lưu lượng kết xuất.
HTML quá lớnChính sách HTML.Từ chối trước khi khởi động Chrome.
Trình duyệt hết thời gian chờRanh giới bộ kết xuất.Báo lỗi kết xuất, và ghi lại tên mẫu, kích thước, chiều rộng và thời gian chờ.
Lỗi bộ phân tích cú phápRanh giới nhập.Lưu một fixture nhỏ đã được làm sạch để gỡ lỗi khi chính sách cho phép.
Rò rỉ tiến trình trình duyệtVòng đời của worker.Đóng khi tắt và khởi động lại sau số lần kết xuất được kiểm soát.
Vấn đề cần lưu tâmMặc địnhKhi nào nên ghi đè
Thời gian chờ kết xuất30 giây.Chỉ tăng cho các tài liệu đã được đo lường và giới hạn.
Kích thước HTML tối đa5,000,000 byte.Hạ thấp cho các endpoint công khai.
SandboxBật.Chỉ tắt khi các ràng buộc của container yêu cầu và máy chủ được cô lập.
Chiều caoTự động khi heightPt <= 0.Dùng chiều cao cố định cho các ràng buộc bố cục nghiêm ngặt.
Tài nguyên bên ngoàiBị chặn bởi chính sách của bộ kết xuất.Chỉ cho phép qua một chính sách tài nguyên đã được rà soát.
  • Các bài kiểm thử kết xuất bao phủ HTML và CSS tiêu biểu.
  • Các bài kiểm thử bảo mật bao phủ HTML quá lớn và các nỗ lực truy cập tài nguyên bị chặn.
  • Các bài kiểm thử nhập xác nhận rằng đối tượng form được trả về có nội dung, media box và tài nguyên.
  • Các bài kiểm thử phân tích cú pháp bao phủ các trường hợp bảng cross-reference (xref), xref stream, object stream và fixture bị lỗi định dạng.
  • Các bài kiểm thử worker gọi close() và xác minh không còn tiến trình trình duyệt nào.
  • Các bài kiểm thử hiệu năng ghi lại thời gian kết xuất theo mẫu và kích thước nội dung.