Config:不可變文件設定
Config 是不可變的文件設定物件。每次變更設定都會透過具型別的 wither 回傳新實例,因此可以在多份文件與多個 worker 之間安全共用。NextPdfConfig 則是獨立的靜態類別,負責保存整個行程共用的 CSS parser 安全限制。
composer require nextpdf/core:^3這兩個類別都隨 core 套件發行。Config 自 1.7.0 起提供。NextPdfConfig 自 2.2.0 起提供。
概念說明
標題為「概念說明」的區段Config 是一個 final readonly 類別,並標註 #[DisallowDynamicProperties]。它只持有純量與 final readonly 值物件(value object),因此整個物件圖都是深度不可變的。它沒有通用的 with(string, mixed) setter;每一項變更都有專屬、具型別的 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。在串流(streaming)模式下,effectiveRetainedNodeBudget() 會回傳 0。否則,它會把值夾限回有效範圍內,作為直接以位置引數建構物件時的縱深防禦檢查。validate() 會強制執行各個單欄位 wither 無法各自察覺的跨欄位不變式。CssLayoutMode::Auto 為保留值,會引發 NotImplementedException。CssRenderingMode::Safe 與 CssLayoutMode::Retained 並用時,會引發 IncompatibleRenderingModeException。auditCollector 是由呼叫端提供的稽核報告收集器。只有當 cssRenderingMode 為 CssRenderingMode::Audit 時才會被取用;此時它會驅動一個私有的 nextpdfAudit XMP 區塊。在其他渲染模式下則會被忽略。
NextPdfConfig 處理的是另一個面向。它是一個無法實例化的靜態工具類別,負責保存整個行程共用的 CSS parser 限制。這些限制分別是樣式表位元組數上限(預設 512 KB)與 CSS 巢狀深度上限(預設 8)。它們是用來抵禦惡意輸入造成資源耗盡的安全邊界,而非各份文件的偏好設定。正因如此,它們才設計成靜態。setter 會夾限到下限(max(1024, …) 位元組、max(1, …) 深度)。resetDefaults() 標註為 @internal,僅供測試使用。
API 介面
標題為「API 介面」的區段| 符號 | 種類 | 主要成員 |
|---|---|---|
NextPDF\Core\Config | final readonly class | 21 個建構式參數;19 個具型別的 wither;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 class | 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.程式碼範例 — 正式環境
標題為「程式碼範例 — 正式環境」的區段建立一份具決定性且已通過驗證的設定,並針對不受信任的輸入,收緊整個行程共用的 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()是唯一會因自身輸入而丟出InvalidArgumentException的 wither(當值落在[5_000, 100_000]之外時)。effectiveRetainedNodeBudget()在串流模式下會回傳0,代表「不套用 Tier-1 預算」,而不是「不允許任何節點」。withLayoutTelemetryCollector()與withTelemetryEnabled()彼此獨立。在未啟用 telemetry 時設定 collector,等於先將它備妥,供日後 canary 使用。啟用 telemetry 但沒有 collector 是合法的,且不會有任何作用。NextPdfConfig是整個行程共用的靜態設定。一次變更會影響該行程中的每一份文件,直到被重設為止。它是一道安全邊界,而非各份文件的偏好設定。請避免把它放在各個請求的變更路徑上。NextPdfConfig::resetDefaults()標註為@internal。請勿在正式環境程式碼中呼叫它。
每個 wither 會配置一個新的 Config,並複製對既有各個值物件的參照。就設定數量而言,這是 O(1),且不會進行深層複製,因為它所持有的每個值本身都是不可變的。NextPdfConfig 的存取子都是靜態欄位讀取,為 O(1)。本參考頁面的 performance_budget 預設為 wall_ms: 1500、peak_mb: 64。
安全注意事項
標題為「安全注意事項」的區段NextPdfConfig 的存在是為了限制 parser 的資源用量。預設 512 KB 的樣式表上限與深度 8 的巢狀上限,可抵禦異常龐大或巢狀過深 CSS 造成的阻斷服務攻擊。當樣式表來源不受信任時,請同時調低這兩項限制。Config::cryptoPolicy 帶有一個 CryptoPolicyInterface,用於強制執行密碼學政策(例如 FIPS profile)。它預設為 null,並透過 withCryptoPolicy() 設定。Config::deterministic 控制固定的時間戳記與識別碼,以產生位元組完全相同的輸出,也是可重現建置的必要條件。
符合性
標題為「符合性」的區段本模組屬於引擎設定,不引用任何規範性標準。會驅動標準行為的設定 — outputColorProfile(OutputIntent 輸出)、cryptoPolicy(FIPS)、deterministic(可重現建置)— 都由實際輸出它們的各個模組,對照其相關條款記錄說明。
另請參閱
標題為「另請參閱」的區段/modules/core/document/— 使用Config的模組/modules/core/valueobjects/—Config使用的PageSize、Margin/modules/core/contracts/—CryptoPolicyInterface、DegradationPolicy/modules/core/event/—Config隨附於DocumentCreatedEvent/modules/core/exception/—InvalidConfigException、NotImplementedException
詞彙表:具型別的 wither · 降級政策 · 值物件