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 頁面。
元件職責
標題為「元件職責」的區段| 元件 | 職責 | 來源 |
|---|---|---|
ChromeHtmlRenderer | 統籌一次繪製;回傳 ChromeRenderResult | src/Artisan/ChromeHtmlRenderer.php |
ChromeRendererConfig | 不可變的組態值物件 | src/Artisan/ChromeRendererConfig.php |
ChromeSecurityPolicy | 輸入驗證 + 安全的 HTML 封套 | src/Artisan/ChromeSecurityPolicy.php |
BrowserPool | Chrome 程序的生命週期與重啟策略 | src/Artisan/BrowserPool.php |
ViewportCalculator | 72 pt/inch ↔ 96 px/inch 換算 | src/Artisan/ViewportCalculator.php |
ChromeRenderResult | 具型別的繪製輸出(ChromeRenderResultInterface) | src/Artisan/ChromeRenderResult.php |
PageImporter | 已剖析的 Chrome 頁面 → ImportedFormXObject | src/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/——生產環境使用