Перейти к содержимому
getnextpdf.com

стабильность: Экспериментальная

PageBackfill: буфер сохранённых страниц

Подключаемое превью. Буфер сохранённых страниц по умолчанию выключен. С ним выключенным писатель — это потоковый сериализатор, каким был всегда, — побайтово идентично. Включайте его только тогда, когда вам действительно нужно рисовать на более ранней странице, и сначала прочитайте список с отказом закрытием ниже.

По умолчанию писатель потоково обрабатывает страницы и сбрасывает их по порядку; после сброса на странице нельзя рисовать снова. Буфер сохранённых страниц — это подключаемая опция, которая держит сброшенные страницы, чтобы ранее сброшенную страницу можно было дозаполнить — нарисовать на более ранней странице — до сериализации документа. Классическое применение — итог или сводный блок, который вы можете разместить только после того, как сверстаны последующие страницы.

Окно терминала
composer require nextpdf/core:^3

Буфер сохранённых страниц поставляется в пакете core. Config::withRetainedPageBuffer() и методы дозаполнения Document помечены @since 6.1.0. По умолчанию остаётся потоковый писатель. ADR-037, который ранее откладывал эту возможность, теперь зафиксирован как реализованный.

Config::withRetainedPageBuffer() подключает документ к сохранённым страницам. После включения Document::setActiveBackfillPage(int $pageIndex) перенаправляет рисование на более раннюю, уже сброшенную страницу; Document::endPageBackfill() возвращает рисование в обычную позицию добавления. Содержимое, которое вы пишете между этими двумя вызовами, попадает на более раннюю страницу. Буфер держит страницы до save(), поэтому дозаполнение применяется до того, как записаны таблица перекрёстных ссылок и трейлер (ISO 32000-2 §7.5).

Граница с отказом закрытием — отклоняемые сочетания

Заголовок раздела «Граница с отказом закрытием — отклоняемые сочетания»

Дозаполнение — это операция произвольного доступа, а несколько функций документа предполагают только добавляемые, потоковые байты. Буфер сохранённых страниц отказывается сочетаться с любой из них, независимо от порядка и до сериализации, поэтому он никогда не может молча сломать подпись или заявление о соответствии:

  • Цифровая подпись.
  • Тегированный PDF (дерево структуры).
  • PDF/A.
  • Линеаризация.
  • Упаковка в потоки объектов.
  • Шифрование.
  • Режим рендеринга Safe CSS.

Подокументный бюджет несжатых байтов ограничивает, сколько может держать буфер; документ, превышающий его, жёстко отказывает, а не потребляет неограниченную память. Потоковое поведение по умолчанию по-прежнему отказывает закрытием в тот момент, когда вызывающий пытается переключиться на произвольный доступ без подключения опции, — включение буфера это единственный способ получить дозаполнение, и он несовместим с перечисленными выше функциями по построению.

СимволРасположениеРоль
Config::withRetainedPageBuffer(bool $enabled = true): selfsrc/Core/Config.phpПодключает документ к буферу сохранённых страниц.
Document::setActiveBackfillPage(int $pageIndex): staticsrc/Core/Document.phpПеренаправляет рисование на более раннюю, уже сброшенную страницу.
Document::endPageBackfill(): staticsrc/Core/Document.phpВозвращает рисование в обычную позицию добавления.

Попытка дозаполнения, нарушающая отклоняемое сочетание, вызывает типизированное исключение конфигурации на границе, а не повреждённый документ.

Зарезервируйте место на первой странице, заполните остальную часть документа, затем дозаполните зарезервированное место значением, вычисленным в конце.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;
use NextPDF\Core\Document;
$config = (new Config())->withRetainedPageBuffer();
$doc = Document::createStandalone($config);
$doc->addPage(); // page 0 — leaves room for a grand total
$doc->writeHtml('<h1>Invoice</h1>');
$doc->addPage(); // page 1 — line items
$doc->writeHtml('<p>Line items…</p>');
$total = 1234.56; // computed after laying out the items
$doc->setActiveBackfillPage(0); // draw back onto page 0
$doc->writeHtml('<p>Grand total: ' . number_format($total, 2) . '</p>');
$doc->endPageBackfill();
$doc->save(__DIR__ . '/invoice.pdf');

Держите буфер выключенным для любого подписанного, тегированного, PDF/A, линеаризованного, зашифрованного документа или документа с потоками объектов — это именно те сочетания, которые буфер отклоняет. Выбирайте один путь явно.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;
use NextPDF\Core\Document;
function renderReport(bool $needsBackfill, bool $mustBeSigned): Document
{
if ($needsBackfill && $mustBeSigned) {
// The buffer refuses to combine with signing. Resolve the requirement
// before building: pre-compute the value, or sign a separate pass.
throw new \LogicException('Back-fill and signing are mutually exclusive.');
}
$config = new Config();
if ($needsBackfill) {
$config = $config->withRetainedPageBuffer();
}
return Document::createStandalone($config);
}
  • Выключено — побайтово идентично. С выключенным буфером писатель потоково обрабатывает как раньше.
  • Взаимоисключаем с подписанием, тегированием, PDF/A, линеаризацией, потоками объектов, шифрованием и режимом Safe CSS. Отказ независим от порядка и срабатывает до сериализации. Планируйте документ под один режим или другой.
  • Бюджет байтов жёстко отказывает. Сохранённый буфер ограничен; документ, превышающий бюджет несжатых байтов, отказывает, а не растёт без предела.
  • Парьте вызовы. Каждый setActiveBackfillPage() должен сопровождаться endPageBackfill(), чтобы последующее содержимое добавлялось нормально.
  • Потоковое поведение по умолчанию отклоняет произвольный доступ. Без подключения опции переключение на произвольный доступ отказывает закрытием. Буфер — единственный поддерживаемый путь.

Буфер сохранённых страниц меняет память на возможность дозаполнения: он держит сброшенные страницы до save(), ограниченный подокументным бюджетом несжатых байтов. Плоский профиль памяти потокового писателя применяется только с выключенным буфером. performance_budget (wall_ms: 1500, peak_mb: 128) отражает более высокий потолок памяти пути с сохранением.

Буфер сохранённых страниц не расширяет поверхность ввода; он меняет, когда сериализуются байты, а не что поглощается. Его отказ сочетаться с шифрованием и подписанием — свойство безопасности: дозаполнение никогда не сможет изменить подписанные или зашифрованные байты задним числом, потому что эти два режима нельзя включить вместе. Бюджет байтов ограничивает память против враждебного документа.

УтверждениеСпецификацияРаздел
Писатель сериализует тело, структуру перекрёстных ссылок и трейлер во время сохранения.ISO 32000-2§7.5

Это превью-возможность. NextPDF отклоняет буфер дозаполнения для подписанных, тегированных, PDF/A, линеаризованных, зашифрованных документов и документов с потоками объектов, поэтому через этот путь он не делает заявления о соответствии для этих профилей. Текст стандартов не воспроизводится.

Адаптер совместимости TCPDF предоставляет эту возможность как расширение конструктора. Сконструируйте адаптер с retainedPageBuffer: true, и тогда вызов setPage() или lastPage(), нацеленный на более раннюю страницу, делегирует дозаполнению ядра вместо того, чтобы вызвать потоковое UnsupportedFeatureException. Этот аргумент конструктора — расширение NextPDF, а не паритет с устаревшим TCPDF — в устаревшем TCPDF такого флага нет. Применяются те же отказы закрытием. Подробности на стороне адаптера см. на странице буфера сохранённых страниц адаптера совместимости.