안정성: 실험적
PageBackfill: 유지 페이지 버퍼
한눈에 보기
섹션 제목: “한눈에 보기”옵트인 프리뷰. 유지 페이지 버퍼는 기본적으로 꺼져 있습니다. 꺼져 있으면, 라이터는 언제나 그래왔던 스트리밍 직렬화기입니다 — 바이트 단위로 동일합니다. 이전 페이지에 정말로 그려야 할 때만 켜고, 먼저 아래의 fail-closed 목록을 읽으세요.
기본적으로 라이터는 페이지를 스트리밍하고 순서대로 플러시합니다. 일단 페이지가 플러시되면 다시 그릴 수 없습니다. 유지 페이지 버퍼는 플러시된 페이지를 보유하여, 이미 플러시된 페이지를 문서가 직렬화되기 전에 백필 — 이전 페이지에 그리기 — 할 수 있게 하는 옵트인입니다. 전형적인 용도는 이후 페이지가 배치된 후에야 배치할 수 있는 합계나 요약 박스입니다.
composer require nextpdf/core:^3유지 페이지 버퍼는 코어 패키지에 포함되어 제공됩니다.
Config::withRetainedPageBuffer()와 Document 백필 메서드는 @since 6.1.0입니다.
기본값은 여전히 스트리밍 라이터입니다. 이전에 이 능력을 연기했던 ADR-037은 이제
구현된 것으로 기록됩니다.
개념 개요
섹션 제목: “개념 개요”Config::withRetainedPageBuffer()는 문서를 유지 페이지로 옵트인합니다. 일단
켜지면, Document::setActiveBackfillPage(int $pageIndex)는 그리기를 이미 플러시된
이전 페이지로 리디렉션하고, Document::endPageBackfill()은 그리기를 정상 추가
위치로 되돌립니다. 두 호출 사이에 쓰는 콘텐츠는 이전 페이지에 자리 잡습니다. 버퍼는
save()까지 페이지를 보유하므로, 백필은 상호 참조 테이블과 트레일러가 쓰여지기
전에 적용됩니다(ISO 32000-2 §7.5).
Fail-closed 경계 — 거부되는 조합
섹션 제목: “Fail-closed 경계 — 거부되는 조합”백필은 임의 접근 연산이며, 여러 문서 기능은 추가 전용이고 스트리밍된 바이트를 가정합니다. 유지 페이지 버퍼는 그것들 중 어느 것과도 결합하기를, 순서와 무관하게, 직렬화 전에 거부하므로, 서명이나 적합성 주장을 결코 조용히 깨뜨릴 수 없습니다.
- 디지털 서명.
- 태그된 PDF(구조 트리).
- PDF/A.
- 선형화.
- 객체 스트림 패킹.
- 암호화.
- Safe CSS 렌더링 모드.
문서별 비압축 바이트 예산이 버퍼가 보유할 수 있는 양을 상한 짓습니다. 그것을 초과하는 문서는 무제한 메모리를 소비하는 대신 하드 실패합니다. 스트리밍 기본값은 호출자가 옵트인 없이 임의 접근 전환을 시도하는 순간 여전히 fail-closed 처리합니다 — 버퍼를 켜는 것이 백필을 얻는 유일한 방법이며, 그것은 구조상 위의 기능들과 호환되지 않습니다.
API 표면
섹션 제목: “API 표면”| 심볼 | 위치 | 역할 |
|---|---|---|
Config::withRetainedPageBuffer(bool $enabled = true): self | src/Core/Config.php | 문서를 유지 페이지 버퍼로 옵트인합니다. |
Document::setActiveBackfillPage(int $pageIndex): static | src/Core/Document.php | 그리기를 이미 플러시된 이전 페이지로 리디렉션합니다. |
Document::endPageBackfill(): static | src/Core/Document.php | 그리기를 정상 추가 위치로 되돌립니다. |
거부되는 조합을 위반하는 백필 시도는 손상된 문서가 아니라 경계에서 타입 지정 구성 예외를 발생시킵니다.
코드 샘플 — 빠른 시작
섹션 제목: “코드 샘플 — 빠른 시작”1페이지에 자리를 예약하고, 문서의 나머지를 채운 다음, 끝에서 계산된 값으로 예약된 자리를 백필합니다.
<?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()과 짝지어져야 이후 콘텐츠가 정상적으로 추가됩니다. - 스트리밍 기본값은 임의 접근을 거부합니다. 옵트인 없이 임의 접근 전환은 fail-closed 처리됩니다. 버퍼가 유일하게 지원되는 경로입니다.
유지 페이지 버퍼는 백필 능력을 위해 메모리를 거래합니다. 문서별 비압축 바이트
예산으로 제한된 채, save()까지 플러시된 페이지를 보유합니다. 스트리밍 라이터의
평탄한 메모리 프로파일은 버퍼가 꺼져 있을 때만 적용됩니다.
performance_budget(wall_ms: 1500, peak_mb: 128)은 유지 경로의 더 높은 메모리
상한을 반영합니다.
보안 참고
섹션 제목: “보안 참고”유지 페이지 버퍼는 입력 표면을 넓히지 않습니다. 무엇이 수집되는지가 아니라 바이트가 언제 직렬화되는지를 바꿉니다. 암호화 및 서명과 결합하기를 거부하는 것은 안전 속성입니다. 두 가지를 함께 활성화할 수 없으므로, 백필은 서명되거나 암호화된 바이트를 사후에 결코 변경할 수 없습니다. 바이트 예산은 적대적 문서에 대해 메모리를 상한 짓습니다.
적합성
섹션 제목: “적합성”| 진술 | 사양 | 절 |
|---|---|---|
| 라이터는 저장 시점에 본문, 상호 참조 구조, 트레일러를 직렬화합니다. | ISO 32000-2 | §7.5 |
이는 프리뷰 능력입니다. NextPDF는 서명되거나, 태그되거나, PDF/A이거나, 선형화되거나, 암호화되거나, 객체 스트림인 문서에 대해 백필 버퍼를 거부하므로, 이 경로를 통해 해당 프로파일에 대한 적합성 주장을 하지 않습니다. 표준 텍스트는 재현되지 않습니다.
Compat(TCPDF) 어댑터
섹션 제목: “Compat(TCPDF) 어댑터”TCPDF 호환성 어댑터는 이 능력을 생성자 확장으로 노출합니다. 어댑터를
retainedPageBuffer: true로 생성하면, 이전 페이지를 대상으로 하는 setPage()
또는 lastPage() 호출이 스트리밍 UnsupportedFeatureException을 발생시키는 대신
코어 백필에 위임합니다. 이 생성자 인수는 NextPDF 확장이지 레거시 TCPDF 패리티가
아닙니다 — 레거시 TCPDF에는 그러한 플래그가 없습니다. 동일한 fail-closed 거부가
적용됩니다. 어댑터 측 세부 사항은 compat 어댑터의 retained-page-buffer 페이지를
참조하세요.