ข้ามไปยังเนื้อหา

ภาพรวม NextPDF Artisan

NextPDF Artisan คือ Chrome bridge สำหรับ NextPDF ที่ส่งส่วนย่อยของ Hypertext Markup Language (HTML) ไปยังกระบวนการ headless Chrome ผ่าน Chrome DevTools Protocol (CDP) รับเอาต์พุตจาก printToPDF แล้วฝังผลลัพธ์ลงในเอกสาร Portable Document Format (PDF) ปลายทางในรูปแบบ Form XObject ข้อความที่ฝังไว้ยังคงเลือกและค้นหาได้

แพ็กเกจ Artisan (nextpdf/artisan) ขยายความสามารถของเอนจิน NextPDF แบบโอเพนซอร์สด้วยตัวเรนเดอร์ที่มอบหมายงานจัดเค้าโครงให้ Chrome ไปป์ไลน์ HTML แบบเนทีฟของ NextPDF ครอบคลุมชุดย่อยของ Cascading Style Sheets (CSS) ที่กว้างอยู่แล้ว ใช้ Artisan bridge กับเอกสารที่ต้องการเค้าโครงระดับ Chrome รวมถึง CSS flexbox และ grid เว็บฟอนต์แบบกำหนดเองที่โหลดจากแหล่ง data Uniform Resource Identifier (URI) และตัวเลือกที่ซับซ้อน โดยยังคงสร้างข้อความแบบเวกเตอร์แทนภาพหน้าจอแบบแรสเตอร์

bridge ทำงานเป็นไปป์ไลน์ของคอมโพเนนต์ขนาดเล็กที่มีหน้าที่เดียว ChromeHtmlRenderer ประสานงานการเรนเดอร์ ChromeSecurityPolicy ตรวจสอบความถูกต้องของอินพุตและห่อหุ้มไว้ในเอกสาร HTML ที่ล็อกอย่างเข้มงวด BrowserPool ดูแลวงจรชีวิตของกระบวนการ Chrome ViewportCalculator แมป PDF point ไปยัง CSS pixel ตัวอ่าน NextPDF\Parser แยกวิเคราะห์เอาต์พุตจาก Chrome และ PageImporter แปลงผลให้เป็น Form XObject ทุกคอมโพเนนต์เป็น final ฉีดผ่านคอนสตรักเตอร์ และระบุชนิดข้อมูลถึง PHPStan level 10

bridge ขึ้นอยู่กับดีเพนเดนซีภายนอก โดยต้องใช้ไลบรารี chrome-php/chrome (^1.15) และไบนารี Chrome หรือ Chromium ที่กระบวนการ PHP เข้าถึงได้ ทั้งสองอย่างไม่ได้รวมมากับแพ็กเกจ เมื่อไม่มีไลบรารีดังกล่าว bridge จะยก ChromeNotAvailableException แทนการล้มเหลวแบบเงียบๆ ดู /integrations/artisan/failure-modes/ ในหน้า /integrations/artisan/troubleshooting/

ตัวเรนเดอร์จะไม่ส่งเนื้อหาไปยัง Chrome จนกว่าอินพุตจะผ่าน ChromeSecurityPolicy::validate() เอกสารที่ Chrome ได้รับจะถูกห่อหุ้มด้วย Content Security Policy (CSP) ที่เข้มงวดเสมอผ่านเฮดเดอร์ Content-Security-Policy และมีการบล็อกเครือข่ายระดับ CDP แบบ defense-in-depth เนื่องจาก bridge ประมวลผล 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
BrowserPoolดูแลวงจรชีวิตของกระบวนการ Chrome และนโยบายการรีสตาร์ตsrc/Artisan/BrowserPool.php
ViewportCalculatorการแปลง 72 pt/inch ↔ 96 px/inchsrc/Artisan/ViewportCalculator.php
ChromeRenderResultเอาต์พุตการเรนเดอร์ที่ระบุชนิดข้อมูล (ChromeRenderResultInterface)src/Artisan/ChromeRenderResult.php
PageImporterหน้า Chrome ที่แยกวิเคราะห์แล้ว → ImportedFormXObjectsrc/Artisan/PageImporter.php
EInvoiceServiceFactoryแฟกทอรีที่ไม่ใช้คอนเทนเนอร์สำหรับสัญญา e-invoice ของ Premiumsrc/Artisan/EInvoiceServiceFactory.php
  • สายเวอร์ชัน อาร์ติแฟกต์ Composer ที่เผยแพร่ติดแท็ก v0.1.0 ส่วน docblock ในซอร์สมี @since 1.7.0 (Chrome bridge) และ @since 1.1.0 (แฟกทอรี e-invoice) ซึ่งทั้งคู่สืบทอดมาจากสายเวอร์ชัน nextpdf/core ก่อนการเปลี่ยนชื่อ แพ็กเกจถูกเปลี่ยนชื่อเป็น nextpdf/artisan ในรายการ CHANGELOG ของ 2.0.0 ให้ถือว่าแท็ก Composer เป็นเวอร์ชันติดตั้งที่เชื่อถือได้ และถือว่าเครื่องหมาย @since เป็นประวัติเวอร์ชันของเอนจิน
  • หน้าแรกเท่านั้น PageImporter::import() มีค่าเริ่มต้นเป็นดัชนีหน้า 0 เนื้อหาที่ล้นไปยังหน้า Chrome หน้าที่สองจะถูกตัดออก เว้นแต่จะระบุความสูงอย่างชัดเจนตามที่อธิบายไว้ในหน้า /integrations/artisan/production-usage/
  • ไม่มีคอนเทนเนอร์ dependency injection (DI) Artisan ไม่ใช้คอนเทนเนอร์ ส่วน EInvoiceServiceFactory ให้สภาพแวดล้อมที่ไม่มี service container มีวิธีสร้างอินสแตนซ์ของบริการอย่างสอดคล้องกัน ดู /integrations/artisan/boot-and-discovery/

การเรนเดอร์แต่ละครั้งมีต้นทุนจากการโหลดหน้า Chrome และการเรียก printToPDF หนึ่งครั้ง BrowserPool รักษากระบวนการ Chrome ให้ทำงานอยู่ระหว่างการเรนเดอร์ และรีสตาร์ตเมื่อครบ 100 การเรนเดอร์เพื่อจำกัดการเติบโตของหน่วยความจำ งานจัดเค้าโครงของ Chrome ไม่ใช่ตัว bridge เอง เป็นปัจจัยหลักที่กำหนดพฤติกรรม Big-O สำหรับงบประมาณที่วัดได้ของโฟลว์อ้างอิงในหน้านี้ ดู performance_budget ในส่วน frontmatter และหน้า /integrations/artisan/production-usage/

bridge เรนเดอร์ HTML ที่อาจไม่น่าเชื่อถือภายใน Chrome อินพุตจะถูกตรวจสอบความถูกต้องทั้งขนาดและเนื้อหาก่อนส่งถึง Chrome เอกสารที่ห่อหุ้มแล้วมี default-src 'none' การบล็อกระดับ CDP จะหยุดคำขอ subresource ทั้งหมด โมเดลการขนส่งและการแยกตัวฉบับเต็ม รวมถึงขีดจำกัดที่ชัดเจนของแฟล็ก Chrome sandbox อยู่ในหน้า /integrations/artisan/security-and-operations/ อย่าถือว่าส่วนนี้เป็นมาตรการรักษาความปลอดภัยที่ครบถ้วน

bridge แบบโอเพนซอร์สเรนเดอร์ HTML ไปเป็น PDF ส่วนระดับ Premium เพิ่มการฝัง e-invoice ที่สอดคล้องตามข้อกำหนด (Pro) และการตรวจสอบความถูกต้อง (Enterprise) บนเอกสารที่เรนเดอร์แล้ว หากไม่ได้ติดตั้งระดับเหล่านั้น EInvoiceServiceFactory จะคืนค่า null ดังนั้นเส้นทางแบบโอเพนซอร์สจึงยังคงทำงานได้อย่างสมบูรณ์โดยไม่ต้องมีระดับเหล่านั้น

  • การติดตั้ง — /integrations/artisan/install/
  • การกำหนดค่า — /integrations/artisan/configuration/
  • เริ่มต้นใช้งานอย่างรวดเร็ว — /integrations/artisan/quickstart/
  • การตั้งค่าตัวเรนเดอร์ Chrome — /integrations/artisan/chrome-renderer-setup/
  • ความปลอดภัยและการดำเนินงาน — /integrations/artisan/security-and-operations/
  • การใช้งานในโปรดักชัน — /integrations/artisan/production-usage/