Transactions (TransactionManager)
Les transactions permettent de prendre un snapshot de l'état du document, rendre du contenu de manière spéculative, puis décider de conserver ou rejeter le résultat. C'est le mécanisme principal pour la logique de mise en page "try-fit".
Vue d'ensemble de l'API
| Méthode | Description | Retourne |
|---|---|---|
startTransaction() | Prendre un snapshot de l'état actuel du document | static |
commitTransaction() | Rejeter le snapshot et conserver tous les changements | static |
rollbackTransaction() | Restaurer le document au snapshot | static |
Les trois méthodes retournent static pour le chaînage fluent.
Comment ça fonctionne
Lorsque vous appelez startTransaction(), le TransactionManager stocke une copie complète de l'état actuel du document — position curseur, nombre de pages, buffers de contenu et compteurs internes. Vous rendez ensuite le contenu normalement.
- Commit rejette le snapshot stocké. Le contenu rendu reste dans le document.
- Rollback remplace l'état actuel par le snapshot stocké. Tout rendu depuis
startTransaction()est rejeté.
Exemple de base
use Yeeefang\TcpdfNext\Core\Document;
$pdf = Document::create()
->addPage()
->setFont('Helvetica', '', 12);
// Essayer d'adapter un bloc sur la page actuelle
$pdf->startTransaction();
$startPage = $pdf->getPage();
$pdf->multiCell(0, 6, $longText);
if ($pdf->getPage() > $startPage) {
// Le contenu a débordé sur la page suivante — rollback et essayer différemment
$pdf->rollbackTransaction();
$pdf->addPage();
$pdf->multiCell(0, 6, $longText);
} else {
// Le contenu tient — le conserver
$pdf->commitTransaction();
}Cas d'usage
Adapter le contenu dans un espace restant
Le cas d'usage le plus courant est de vérifier si le contenu tient sur la page actuelle avant de le valider :
use Yeeefang\TcpdfNext\Core\Document;
$pdf = Document::create()
->addPage()
->setFont('Helvetica', '', 10);
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();
$pdf->setFont('Helvetica', 'B', 14)
->cell(0, 8, $section['title'], newLine: true)
->setFont('Helvetica', '', 10)
->multiCell(0, 5, $section['body']);
} else {
$pdf->commitTransaction();
}
}Mesurer la hauteur du contenu
Utiliser une transaction pour mesurer combien d'espace vertical le contenu consommera sans le placer réellement :
$pdf->startTransaction();
$startY = $pdf->getY();
$pdf->multiCell(0, 5, $text);
$endY = $pdf->getY();
$height = $endY - $startY;
$pdf->rollbackTransaction();
// Maintenant utiliser $height pour les décisions de mise en pageContraintes importantes
Pas d'imbrication
Les transactions imbriquées ne sont pas supportées. Appeler startTransaction() alors qu'une transaction est déjà active lèvera une exception. Toujours commit ou rollback avant de démarrer une nouvelle transaction.
Impact sur les performances
Une transaction stocke un snapshot complet de l'état du document. Pour les documents avec de nombreuses pages et de gros buffers de contenu, cela peut temporairement doubler l'utilisation mémoire. Gardez les blocs de transaction aussi petits que possible — snapshot, rendu, décision, puis commit ou rollback immédiatement.
Bonnes pratiques
- Gardez le code entre
startTransaction()etcommitTransaction()/rollbackTransaction()minimal. - Assurez-vous toujours que chaque
startTransaction()est apparié avec exactement uncommitTransaction()ourollbackTransaction(). - N'effectuez pas d'I/O fichier ou envoi de sortie dans un bloc de transaction — seules les mutations de document peuvent être rollback.
- Préférez mesurer de petites sections plutôt qu'envelopper toute la génération de document dans une transaction.