Skip to content

交易 (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 或送出輸出 — 只有文件內部的變動才能被回滾。
  • 優先測量小範圍內容,而非用交易包裹整個文件產生流程。

以 LGPL-3.0-or-later 授權釋出。