跳到內容

NextPDF Artisan 總覽

NextPDF Artisan 是 NextPDF 的 Chrome 橋接。它透過 Chrome DevTools Protocol 將 HTML 片段送往 headless Chrome 程序,擷取 printToPDF 的輸出,再將結果以 Form XObject 嵌入目標文件。嵌入後的文字仍可選取、可搜尋。

Artisan 套件(nextpdf/artisan)為開源的 NextPDF 引擎擴充了一個將版面配置委派給 Chrome 的 renderer(渲染器)。NextPDF 原生的 HTML 管線已涵蓋相當廣泛的 CSS 子集。Artisan 橋接適用於需要 Chrome 等級版面配置的文件——CSS flexbox 與 grid、從 data URI 載入的自訂網頁字型,以及複雜的選擇器——同時仍產生向量文字,而不是點陣化的螢幕截圖。

這個橋接是一條由一系列小型、單一職責元件組成的管線。ChromeHtmlRenderer 負責統籌一次繪製。ChromeSecurityPolicy 驗證輸入,並將它包進一份受嚴格限制的 HTML 文件。BrowserPool 掌管 Chrome 程序的生命週期。ViewportCalculator 將 PDF 點數對映到 CSS 像素。NextPDF\Parser 讀取器剖析 Chrome 的輸出,再由 PageImporter 將它轉換成 Form XObject。每個元件都是 final、採用建構子注入,並以 PHPStan level 10 完整標註型別。

這個橋接依賴外部相依套件。它需要 chrome-php/chrome 函式庫(^1.15),以及 PHP 程序可存取的 Chrome 或 Chromium 執行檔。兩者都不會隨套件附帶。當函式庫不存在時,這個橋接會丟出 ChromeNotAvailableException,而不會靜默降級——詳見 /integrations/artisan/troubleshooting/ 頁面上的 /integrations/artisan/failure-modes/ 一節。

在輸入通過 ChromeSecurityPolicy::validate() 之前,繪製永遠不會抵達 Chrome;而且 Chrome 收到的文件一律以嚴格的 Content-Security-Policy 與一道縱深防禦的 CDP 網路封鎖包覆。由於這個橋接處理的可能是未受信任的 HTML,它的傳輸與隔離態勢已明確記載於 /integrations/artisan/security-and-operations/ 頁面,而不是在此摘要帶過。

這是套件出貨狀態下觀察到的行為,已對照 src/Artisan/tests/Unit/Artisan/ 測試套組驗證。這並不是主張它與互動式 Chrome 瀏覽器逐像素一致:動畫會以最終影格擷取、版面配置不依賴 JavaScript,而且只會匯入第一個 Chrome 頁面。

HTML fragment

ChromeSecurityPolicy::validate()

ChromeSecurityPolicy::wrapHtml()

CSP + reset CSS

BrowserPool

headless Chrome

CDP: Network.setBlockedURLs '*'

Page.setDocumentContent

Chrome printToPDF

NextPDF\\Parser\\PdfReader

PageImporter → Form XObject

Embedded in target PDF

(text selectable)

Diagram
元件職責來源
ChromeHtmlRenderer統籌一次繪製;回傳 ChromeRenderResultsrc/Artisan/ChromeHtmlRenderer.php
ChromeRendererConfig不可變的組態值物件src/Artisan/ChromeRendererConfig.php
ChromeSecurityPolicy輸入驗證 + 安全的 HTML 封套src/Artisan/ChromeSecurityPolicy.php
BrowserPoolChrome 程序的生命週期與重啟策略src/Artisan/BrowserPool.php
ViewportCalculator72 pt/inch ↔ 96 px/inch 換算src/Artisan/ViewportCalculator.php
ChromeRenderResult具型別的繪製輸出(ChromeRenderResultInterfacesrc/Artisan/ChromeRenderResult.php
PageImporter已剖析的 Chrome 頁面 → ImportedFormXObjectsrc/Artisan/PageImporter.php
EInvoiceServiceFactory供 Premium 電子發票合約使用、無需容器的工廠src/Artisan/EInvoiceServiceFactory.php
  • **版本沿革。**發布到 Composer 的成品標記為 v0.1.0。原始碼 docblock 帶有 @since 1.7.0(Chrome 橋接)與 @since 1.1.0(電子發票工廠),兩者都繼承自更名前的 nextpdf/core 版本線;套件更名為 nextpdf/artisan 的時點,對應 2.0.0 的 CHANGELOG 條目。請將 Composer 標籤視為權威的安裝版本,並將 @since 標記視為引擎版本的 provenance(來源資訊)。
  • 僅限第一頁。 PageImporter::import() 預設使用頁面 Index(索引)0。溢位到第二個 Chrome 頁面的內容會被裁切,除非明確指定高度——此點在 /integrations/artisan/production-usage/ 頁面說明。
  • 沒有 DI 容器。 Artisan 不使用容器。EInvoiceServiceFactory 為沒有服務容器的環境提供一致的實例化介面;參見 /integrations/artisan/boot-and-discovery/.

每次繪製都會付出 Chrome 載入頁面與 printToPDF 的成本。BrowserPool 會讓 Chrome 程序在多次繪製之間持續存活,並每 100 次繪製重啟一次,以限制記憶體成長。Big-O 主要取決於 Chrome 對輸入進行版面配置的成本,而非橋接本身。關於本頁參考流程的實測預算,請見 front-matter 中的 performance_budget 與 /integrations/artisan/production-usage/ 頁面。

這個橋接會在 Chrome 內繪製可能未受信任的 HTML。輸入在送進 Chrome 之前,已先經過大小與內容驗證。包覆後的文件帶有 default-src 'none'。一道 CDP 層級的封鎖會擋下每一個子資源請求。完整的傳輸與隔離模型——包括 Chrome sandbox 旗標的明確限制——記載於 /integrations/artisan/security-and-operations/ 頁面。請勿將本節視為完整的安全態勢。

開源橋接會將 HTML 繪製成 PDF。Premium 各層級會在繪製好的文件之上,再疊加合規的電子發票嵌入(Pro)與驗證(Enterprise)。當這些層級未安裝時,EInvoiceServiceFactory 會回傳 null,因此開源路徑在沒有它們的情況下仍完全可用。

  • /integrations/artisan/install/——安裝
  • /integrations/artisan/configuration/——設定
  • /integrations/artisan/quickstart/——快速上手
  • /integrations/artisan/chrome-renderer-setup/——Chrome 繪製器設定
  • /integrations/artisan/security-and-operations/——安全性與維運
  • /integrations/artisan/production-usage/——生產環境使用