交易 (TransactionManager)
交易機制讓你能對文件狀態建立快照,進行試探性渲染,然後再決定保留或捨棄結果。這是「嘗試放入」版面邏輯的核心手段。
API 概覽
| 方法 | 說明 | 回傳 |
|---|---|---|
startTransaction() | 對目前文件狀態建立快照 | static |
commitTransaction() | 捨棄快照,保留所有變更 | static |
rollbackTransaction() | 將文件還原至快照狀態 | static |
運作原理
呼叫 startTransaction() 時,TransactionManager 會完整複製當前文件狀態 — 包含游標位置、頁數、內容緩衝區與內部計數器。之後照常渲染內容。提交會捨棄快照並保留變更;回滾會用快照取代當前狀態,捨棄所有已渲染的內容。
基本範例
php
use Yeeefang\TcpdfNext\Core\Document;
$pdf = Document::create()->addPage()->setFont('Helvetica', '', 12);
// 嘗試將區塊放入當前頁面
$pdf->startTransaction();
$startPage = $pdf->getPage();
$pdf->multiCell(0, 6, $longText);
if ($pdf->getPage() > $startPage) {
// 內容溢出至下一頁 — 回滾後換頁重新渲染
$pdf->rollbackTransaction();
$pdf->addPage()->multiCell(0, 6, $longText);
} else {
$pdf->commitTransaction();
}使用場景:嘗試放入剩餘空間
最常見的用途是在提交前檢查內容是否放得進當前頁面:
php
foreach ($sections as $section) {
$pdf->startTransaction();
$startPage = $pdf->getPage();
$pdf->setFont('Helvetica', 'B', 14)
->cell(0, 8, $section['title'], newLine: true)
->setFont('Helvetica', '', 10)
->multiCell(0, 5, $section['body']);
if ($pdf->getPage() > $startPage) {
$pdf->rollbackTransaction();
$pdf->addPage()
->setFont('Helvetica', 'B', 14)
->cell(0, 8, $section['title'], newLine: true)
->setFont('Helvetica', '', 10)
->multiCell(0, 5, $section['body']);
} else {
$pdf->commitTransaction();
}
}使用場景:測量內容高度
透過交易來測量內容實際需要的垂直空間,而不真正放入文件中:
php
$pdf->startTransaction();
$startY = $pdf->getY();
$pdf->multiCell(0, 5, $text);
$height = $pdf->getY() - $startY;
$pdf->rollbackTransaction();
// 接下來就能用 $height 做版面決策不支援巢狀交易
巢狀交易不受支援。在已有進行中的交易時再次呼叫 startTransaction() 會拋出例外。務必先提交或回滾後才能開始新的交易。
效能影響
交易會儲存完整的文件狀態快照。對於頁數多、內容緩衝區大的文件,這可能導致記憶體用量暫時倍增。請盡量縮小交易區塊 — 快照、渲染、判斷,然後立即提交或回滾。
最佳實踐
- 將
startTransaction()與commitTransaction()/rollbackTransaction()之間的程式碼量降到最低。 - 確保每個
startTransaction()都對應恰好一次commitTransaction()或rollbackTransaction()。 - 不要在交易區塊內進行檔案 I/O 或送出輸出 — 只有文件內部的變動才能被回滾。
- 優先測量小範圍內容,而非用交易包裹整個文件產生流程。