Config: การกำหนดค่าเอกสารที่ไม่เปลี่ยนรูป
ภาพรวมโดยย่อ
หัวข้อที่มีชื่อว่า “ภาพรวมโดยย่อ”Config เป็นอ็อบเจ็กต์การกำหนดค่าเอกสารที่ไม่เปลี่ยนรูป เมื่อปรับการตั้งค่าใดการตั้งค่าหนึ่ง wither ที่มีชนิดข้อมูลกำกับจะคืนอินสแตนซ์ใหม่ จึงแชร์การกำหนดค่าระหว่างเอกสารและเวิร์กเกอร์ได้อย่างปลอดภัย NextPdfConfig เป็นคลาสสแตติกที่แยกต่างหากสำหรับเก็บขีดจำกัดด้านความปลอดภัยของตัวแยกวิเคราะห์ Cascading Style Sheets (CSS) ในระดับทั้งกระบวนการ
การติดตั้ง
หัวข้อที่มีชื่อว่า “การติดตั้ง”composer require nextpdf/core:^3คลาสทั้งสองเป็นส่วนหนึ่งของแพ็กเกจ core โดย Config มีมาตั้งแต่เวอร์ชัน 1.7.0 และ NextPdfConfig มีมาตั้งแต่เวอร์ชัน 2.2.0
ภาพรวมเชิงแนวคิด
หัวข้อที่มีชื่อว่า “ภาพรวมเชิงแนวคิด”Config เป็นคลาส final readonly ที่กำกับด้วย #[DisallowDynamicProperties] คลาสนี้เก็บเฉพาะค่าสเกลาร์และอ็อบเจ็กต์ค่าแบบ final readonly ดังนั้นกราฟทั้งหมดจึงไม่เปลี่ยนรูปอย่างสมบูรณ์ คลาสนี้ไม่มีเซ็ตเตอร์ทั่วไป with(string, mixed) การเปลี่ยนแปลงแต่ละครั้งใช้ wither เฉพาะที่มีชนิดข้อมูลกำกับ รวม 19 ตัว ตั้งแต่ withPageSize(), withMargins(), withCompress() ไปจนถึง withOutputColorProfile() และแต่ละตัวจะสร้างอ็อบเจ็กต์ขึ้นใหม่ด้วยอาร์กิวเมนต์แบบมีชื่อ การสร้างใหม่ด้วยอาร์กิวเมนต์แบบมีชื่อเป็นการออกแบบโดยเจตนา เมื่อเพิ่มพารามิเตอร์ของคอนสตรักเตอร์ wither ที่มีอยู่ อาร์กิวเมนต์ตามตำแหน่งจะไม่เลื่อนอย่างเงียบ ๆ การทดสอบความเข้ากันได้ใช้ reflection เพื่อตรึงรายการเมท็อดสาธารณะและจำนวนพารามิเตอร์ การเบี่ยงเบนของลายเซ็นเมท็อดจะทำให้การรวมรหัสต่อเนื่อง (CI) ล้มเหลว
คอนสตรักเตอร์เปิดเผยพื้นผิวการกำหนดค่าพร้อมค่าเริ่มต้นที่ปลอดภัย:
| พารามิเตอร์ | ชนิดข้อมูล | ค่าเริ่มต้น |
|---|---|---|
pageSize | PageSize | PageSize(595.276, 841.890, 'A4') |
margins | Margin | Margin(10.0, 10.0, 10.0, 10.0) |
compress | bool | true |
autoPageBreak | bool | true |
breakMargin | float | 20.0 |
lang | string (BCP-47) | '' |
fontsDirectory | string | '' |
imageCacheBytes | int | 52_428_800 |
deterministic | ?DeterministicSettings | null |
cryptoPolicy | ?CryptoPolicyInterface | null |
branding | ?BrandingConfig | null |
degradationPolicy | DegradationPolicy | Balanced |
degradationOverrides | array<string, DegradationPolicy> | [] |
cssRenderingMode | CssRenderingMode | Normal |
auditCollector | ?AuditCollector | null |
cssFeatureFlags | ?CssFeatureFlags | null |
cssLayoutMode | CssLayoutMode | Streaming |
retainedNodeBudget | int | 50_000 |
layoutTelemetryCollector | ?LayoutTelemetryCollector | null |
telemetryEnabled | bool | false |
outputColorProfile | OutputColorProfile | DeviceRGB |
มีการตั้งค่าสามรายการที่บังคับขอบเขตของค่า retainedNodeBudget โดยรับช่วงปิด [5_000, 100_000] (ค่าคงที่ RETAINED_NODE_BUDGET_MIN, RETAINED_NODE_BUDGET_MAX ค่าเริ่มต้น RETAINED_NODE_BUDGET_DEFAULT) withRetainedNodeBudget() จะโยน InvalidArgumentException เมื่อค่าอยู่นอกช่วงดังกล่าว effectiveRetainedNodeBudget() คืนค่า 0 ในโหมดสตรีมมิง มิฉะนั้นจะหนีบค่ากลับเข้าสู่ช่วง เป็นการตรวจสอบเชิงป้องกันหลายชั้น (defense-in-depth) เพื่อรับมือกับการสร้างตามตำแหน่งโดยตรง validate() บังคับค่าคงตัวข้ามฟิลด์ที่ wither รายฟิลด์ไม่สามารถตรวจพบได้ด้วยตนเอง CssLayoutMode::Auto ถูกสงวนไว้และจะยก NotImplementedException ส่วน CssRenderingMode::Safe ร่วมกับ CssLayoutMode::Retained จะยก IncompatibleRenderingModeException auditCollector คือตัวเก็บรายงานการตรวจสอบ (audit) ที่ผู้เรียกใช้จัดเตรียมมา โดยจะถูกใช้เฉพาะเมื่อ cssRenderingMode เป็น CssRenderingMode::Audit ซึ่งจะขับเคลื่อนบล็อก Extensible Metadata Platform (XMP) ส่วนตัวชื่อ nextpdfAudit โหมดการเรนเดอร์อื่นจะไม่สนใจค่านี้
NextPdfConfig ทำหน้าที่ในขอบเขตที่แยกต่างหาก เป็นยูทิลิตีสแตติกที่สร้างอินสแตนซ์ไม่ได้ และเก็บขีดจำกัดของตัวแยกวิเคราะห์ CSS ในระดับทั้งกระบวนการ ขีดจำกัดดังกล่าวคือจำนวนไบต์สูงสุดของสไตล์ชีต (ค่าเริ่มต้น 512 KB) และความลึกสูงสุดของการซ้อน CSS (ค่าเริ่มต้น 8) ทั้งสองเป็นขอบเขตด้านความปลอดภัยที่ป้องกันอินพุตที่เป็นอันตรายไม่ให้ใช้ทรัพยากรจนหมด ไม่ใช่การกำหนดค่าตามแต่ละเอกสาร ด้วยเหตุนี้ทั้งสองจึงเป็นแบบสแตติก เซ็ตเตอร์จะหนีบค่าไว้ที่ค่าต่ำสุด (max(1024, …) ไบต์, max(1, …) สำหรับความลึก) resetDefaults() ถูกกำกับด้วย @internal สำหรับใช้ในการทดสอบเท่านั้น
พื้นผิว API
หัวข้อที่มีชื่อว่า “พื้นผิว API”| สัญลักษณ์ | ประเภท | สมาชิกสำคัญ |
|---|---|---|
NextPDF\Core\Config | คลาส final readonly | พารามิเตอร์คอนสตรักเตอร์ 21 ตัว; wither ที่มีชนิดข้อมูลกำกับ 19 ตัว; validate(), isSafeMode(), isRetainedMode(), effectiveRetainedNodeBudget(), resolveFeatureFlags() |
NextPDF\Core\Config::RETAINED_NODE_BUDGET_MIN | const int | 5_000 |
NextPDF\Core\Config::RETAINED_NODE_BUDGET_MAX | const int | 100_000 |
NextPDF\Core\Config::RETAINED_NODE_BUDGET_DEFAULT | const int | 50_000 |
NextPDF\Core\NextPdfConfig | คลาส final | setMaxCssBytes(), getMaxCssBytes(), setMaxCssNestingDepth(), getMaxCssNestingDepth(), resetDefaults() (@internal) |
เมท็อด Wither: withPageSize, withMargins, withCompress, withAutoPageBreak, withLang, withFontsDirectory, withImageCacheBytes, withDeterministic, withCryptoPolicy, withBranding, withDegradationPolicy, withDegradationOverride, withCssRenderingMode, withCssFeatureFlags, withCssLayoutMode, withRetainedNodeBudget, withLayoutTelemetryCollector, withTelemetryEnabled, withOutputColorProfile
ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — เริ่มต้นอย่างรวดเร็ว”เริ่มจากค่าเริ่มต้นแล้วปรับการตั้งค่าสองรายการ
<?php
declare(strict_types=1);
use NextPDF\Core\Config;use NextPDF\ValueObjects\Margin;use NextPDF\ValueObjects\PageSize;
$config = (new Config()) ->withPageSize(PageSize::Letter()) ->withMargins(Margin::uniform(18.0));
// Each wither returns a new instance; the original is unchanged.ตัวอย่างโค้ด — การใช้งานจริง
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — การใช้งานจริง”ประกอบการกำหนดค่าแบบกำหนดได้ (deterministic) ที่ผ่านการตรวจสอบแล้ว และปรับขีดจำกัด CSS ระดับทั้งกระบวนการให้เข้มงวดขึ้นสำหรับอินพุตที่ไม่น่าเชื่อถือ
<?php
declare(strict_types=1);
use NextPDF\Core\Config;use NextPDF\Core\CssRenderingMode;use NextPDF\Core\NextPdfConfig;use NextPDF\ValueObjects\Margin;use NextPDF\ValueObjects\PageSize;
$config = (new Config()) ->withPageSize(PageSize::A4()) ->withMargins(Margin::symmetric(vertical: 20.0, horizontal: 15.0)) ->withCompress(true) ->withCssRenderingMode(CssRenderingMode::Safe);
// Reject mutually exclusive modes before generation starts.$config->validate();
// Process-wide hardening for hostile stylesheet input.NextPdfConfig::setMaxCssBytes(262_144); // 256 KBNextPdfConfig::setMaxCssNestingDepth(4);กรณีขอบและข้อควรระวัง
หัวข้อที่มีชื่อว่า “กรณีขอบและข้อควรระวัง”Configจะไม่บังคับกฎข้ามฟิลด์ใด ๆ จนกว่าจะเรียกvalidate()wither ไม่สามารถตรวจพบความขัดแย้งระหว่างSafeกับRetainedได้ด้วยตนเอง จึงต้องเรียกvalidate()ก่อนการสร้างเอกสารwithRetainedNodeBudget()เป็น wither เพียงตัวเดียวที่โยนข้อยกเว้นจากอินพุตของตนเอง (InvalidArgumentExceptionเมื่ออยู่นอก[5_000, 100_000])effectiveRetainedNodeBudget()คืนค่า0ในโหมดสตรีมมิง ค่านี้สื่อความหมายว่า “งบประมาณระดับ Tier-1 ไม่มีผลบังคับใช้” ไม่ใช่ “ไม่อนุญาตให้มีโหนด”withLayoutTelemetryCollector()และwithTelemetryEnabled()เป็นอิสระต่อกัน การเชื่อมต่อตัวเก็บข้อมูลโดยไม่เปิดใช้งานเทเลเมทรีเป็นการเตรียมไว้สำหรับ canary ในภายหลัง ส่วนการเปิดใช้งานเทเลเมทรีโดยไม่มีตัวเก็บข้อมูลถือว่าถูกต้องและไม่มีผลใด ๆNextPdfConfigเป็นแบบทั้งกระบวนการและสแตติก การเปลี่ยนแปลงจะส่งผลต่อทุกเอกสารในกระบวนการจนกว่าจะรีเซ็ต เป็นขอบเขตด้านความปลอดภัย ไม่ใช่การกำหนดค่าตามแต่ละเอกสาร จึงควรเก็บไว้นอกเส้นทางการเปลี่ยนแปลงค่าตามแต่ละคำขอNextPdfConfig::resetDefaults()เป็น@internalอย่าเรียกใช้ในโค้ดสำหรับการใช้งานจริง
ประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ประสิทธิภาพ”wither จะจัดสรร Config ใหม่หนึ่งตัวและคัดลอกการอ้างอิงไปยังอ็อบเจ็กต์ค่าที่มีอยู่แล้ว การดำเนินการเป็น O(1) ตามจำนวนการตั้งค่า และไม่ทำการคัดลอกแบบลึก เพราะค่าทุกค่าที่ถือไว้ไม่เปลี่ยนรูป NextPdfConfig มีตัวเข้าถึง (accessor) ที่เป็นการอ่านฟิลด์สแตติกแบบ O(1) ค่า performance_budget เริ่มต้นสำหรับหน้าอ้างอิงนี้คือ wall_ms: 1500, peak_mb: 64
หมายเหตุด้านความปลอดภัย
หัวข้อที่มีชื่อว่า “หมายเหตุด้านความปลอดภัย”NextPdfConfig จำกัดการใช้ทรัพยากรของตัวแยกวิเคราะห์ ขีดจำกัดสไตล์ชีตเริ่มต้น 512 KB และขีดจำกัดความลึกการซ้อนที่ 8 ช่วยป้องกันการปฏิเสธการให้บริการ (denial-of-service) จาก CSS ที่มีขนาดใหญ่หรือซ้อนลึกอย่างผิดปกติ ควรลดขีดจำกัดทั้งสองลงเมื่อแหล่งที่มาของสไตล์ชีตไม่น่าเชื่อถือ Config::cryptoPolicy ถือ CryptoPolicyInterface ไว้สำหรับบังคับใช้นโยบายการเข้ารหัสลับ เช่น โปรไฟล์ Federal Information Processing Standards (FIPS) โดยมีค่าเป็น null เป็นค่าเริ่มต้น และตั้งค่าผ่าน withCryptoPolicy() Config::deterministic ควบคุมการประทับเวลาและตัวระบุที่ตายตัวเพื่อให้ได้ผลลัพธ์ที่เหมือนกันทุกไบต์ และจำเป็นสำหรับการสร้างที่ทำซ้ำได้ (reproducible builds)
ความสอดคล้อง
หัวข้อที่มีชื่อว่า “ความสอดคล้อง”โมดูลนี้เป็นการกำหนดค่าของเอนจิน และไม่มีการอ้างอิงมาตรฐานเชิงบรรทัดฐาน การตั้งค่าที่ขับเคลื่อนพฤติกรรมตามมาตรฐาน รวมถึง outputColorProfile (การปล่อย OutputIntent), cryptoPolicy (FIPS), และ deterministic (reproducible builds) ได้รับการบันทึกไว้ตามข้อกำหนดของแต่ละมาตรฐานในโมดูลที่ปล่อยค่าเหล่านั้น
ดูเพิ่มเติม
หัวข้อที่มีชื่อว่า “ดูเพิ่มเติม”/modules/core/document/— ผู้ใช้งานConfig/modules/core/valueobjects/—PageSize,Marginที่ใช้โดยConfig/modules/core/contracts/—CryptoPolicyInterface,DegradationPolicy/modules/core/event/—Configที่ส่งมากับDocumentCreatedEvent/modules/core/exception/—InvalidConfigException,NotImplementedException
อภิธานศัพท์: typed wither · degradation policy · value object