Pro エディション
差分
NextPDF\Pro\Diff は、2 つの PDF ドキュメントを比較し、何が変わったかをレポートします。クイックパスはページ整列されたテキスト差分を生成し、構造化パスは画像とメタデータの変更検出を追加して、結果を JSON または HTML として整形します。
提供状況とライセンス
「提供状況とライセンス」という見出しのセクションこの機能は NextPDF Pro(nextpdf/pro)に同梱され、Pro ティアのライセンスエンベロープで有効になります。そのエンタイトルメントがないデプロイメントでは、この機能のクラスは読み込まれません。エディションを比較してライセンスを取得する。
差分のクラスをゲートするランタイムの機能フラグはありません。Pro パッケージがインストールされていれば常に存在します。
インストール
「インストール」という見出しのセクションcomposer require nextpdf/pro:^3概念の概要
「概念の概要」という見出しのセクションPdfDiffer::compare() は、各ドキュメントからページごとにテキストを抽出して行に分割し、ページのペアごとに Myers の行差分を実行して、追加・削除・変更された領域を生成します。テキスト抽出は、ISO 32000-2:2020 §9.4 のテキスト表示演算子(Tj、TJ、')を解析します。
StructuredDiffer はその上に構築されます。テキスト領域を段落レベルの変更にグループ化し、埋め込み画像を比較し、メタデータを比較し、集約サマリーを持つ StructuredDiffResult を生成します。DiffFormatter は、その結果を JSON 文字列または HTML レポートフラグメントにシリアライズします。
オプションの Artisan PDF リーダーがインストールされている場合、テキスト抽出はそれを用いてページ単位で正確な内容を取得します。そうでない場合は、上限付きのバイトレベルのフォールバックがコンテンツストリームを直接スキャンします。
なぜこの仕組みなのか
「なぜこの仕組みなのか」という見出しのセクションこの差分機能は、レンダリングされたピクセルではなく、抽出されたテキストと構造を比較します。構造的な比較は決定的で低コストであり、レビュー担当者が気にする編集上の変更に対応づけられます。ピクセル差分では、アンチエイリアシングやフォントヒンティングのノイズをコンテンツとして誤って検出してしまいます。PDF は読み取り可能な文字ではなくグリフと位置情報を格納しているため、すべての比較はまずコンテンツストリームからテキストを再構築します。この抽出ステップこそが、Artisan リーダーが精度を高める理由であり、上限付きの FlateDecode フォールバックがカバレッジと引き換えに安全性を取る理由であり、スキャンされたページがほとんど差分にならない理由です。ページの整列は予測可能性のためにインデックスベースを維持しており、挿入されたページは明確な下流側のずれとして読み取られます。
設計の背景: PDF のテキストは本当のテキストではない理由。
振る舞いの契約
「振る舞いの契約」という見出しのセクション- 入力。 ソースとターゲットの生 PDF バイト。
%PDFで始まらないバッファはInvalidArgumentExceptionを発生させます。 - 出力(クイックパス)。
added、removed、modifiedの領域リストと、isIdentical()、hasDifferences()、totalChanges()を持つDiffResult。 - 出力(構造化パス)。 段落差分、画像差分、メタデータ変更、
DiffSummaryを持つStructuredDiffResult。 - レポート出力。
DiffFormatterは JSON 文字列または HTML フラグメントを出力します。視覚的な左右並列レッドライン PDF は生成しません。 - リソースの上限。 解凍後のコンテンツストリームサイズは、解凍爆弾を防ぐために上限が設けられています。バイトレベルのスキャナーは、細工された入力に対する破滅的な正規表現バックトラッキングを回避します。
- 決定性。 同一の入力に対して、差分領域と整形された出力は安定しています。
公開 API サーフェス
「公開 API サーフェス」という見出しのセクション| 型 | 種別 | 主なメンバー |
|---|---|---|
NextPDF\Pro\Diff\PdfDiffer | final class | static compare(string $sourcePdf, string $targetPdf): DiffResult, static compareTexts(array $sourcePages, array $targetPages): DiffResult, static extractText(string $contentStream): string |
NextPDF\Pro\Diff\StructuredDiffer | final class | __construct(?ImageDiffer $imageDiffer = null, ?MetadataDiffer $metadataDiffer = null), compare(string $sourcePdf, string $targetPdf): StructuredDiffResult |
NextPDF\Pro\Diff\DiffFormatter | final class | toJson(StructuredDiffResult $result): string, toHtml(StructuredDiffResult $result): string |
NextPDF\Pro\Diff\DiffResult | final readonly class | array $added, array $removed, array $modified, isIdentical(): bool, hasDifferences(): bool, totalChanges(): int |
NextPDF\Pro\Diff\StructuredDiffResult | final readonly class | テキスト差分、段落、画像、メタデータ変更、サマリー |
NextPDF\Pro\Diff\DiffType | enum | Added, Removed, Modified, Unchanged |
コードサンプル — クイックスタート
「コードサンプル — クイックスタート」という見出しのセクション<?php
declare(strict_types=1);
use NextPDF\Pro\Diff\PdfDiffer;
$diff = PdfDiffer::compare( file_get_contents('v1.pdf'), file_get_contents('v2.pdf'),);
if ($diff->hasDifferences()) { echo $diff->totalChanges(), " text changes detected\n";}コードサンプル — 本番
「コードサンプル — 本番」という見出しのセクション<?php
declare(strict_types=1);
use NextPDF\Pro\Diff\DiffFormatter;use NextPDF\Pro\Diff\StructuredDiffer;
function reviewReport(string $oldPdf, string $newPdf): string{ $result = (new StructuredDiffer())->compare($oldPdf, $newPdf);
// JSON for machine consumption; toHtml() for a review UI fragment. return (new DiffFormatter())->toJson($result);}エッジケースと落とし穴
「エッジケースと落とし穴」という見出しのセクション- 差分はインデックスでページ整列されます。早い位置にページを挿入すると以降のすべてのページがずれ、下流側で大量の変更が報告されます。これはインデックス整列比較として想定どおりの挙動です。
- 画像比較は、追加・削除・変更された埋め込み画像を検出します。知覚的なビジュアル差分ではなく、ページをピクセルレンダリングしません。
- スキャンされた画像のみの PDF は、OCR が行われないため、テキスト差分がほとんど、またはまったく生成されません。
- オプションの Artisan リーダーがない場合、抽出は上限付きのフォールバックを用います。高度に圧縮されたドキュメントでは、テキストのカバレッジが低下する場合があります。
パフォーマンス
「パフォーマンス」という見出しのセクションテキスト抽出はドキュメントのバイト数に対して線形です。Myers 差分は、類似したドキュメントではほぼ線形であり、ページペアごとの最悪ケースでは二次です。解凍キャップがメモリの上限を決めます。performance_budget を参照してください。
セキュリティに関する注意
「セキュリティに関する注意」という見出しのセクションバイトレベルのフォールバックは、細工された PDF に対する破滅的なバックトラッキングを避けるため、上限のない正規表現の代わりに strpos ベースのスキャンを用い、解凍出力を上限で制限します。差分は埋め込みスクリプトを実行しません。Core のセキュリティモデルを参照してください。
| 主張 | 仕様の条項 | ステータス |
|---|---|---|
抽出のために Tj テキスト演算子を解析 | ISO 32000-2:2020 §9.4 | 検証済み(ユニットスイート) |
抽出のために TJ 配列テキスト演算子を解析 | ISO 32000-2:2020 §9.4 | 検証済み(ユニットスイート) |
| 視覚的な左右並列レッドライン PDF 出力 | — | 非対応(JSON/HTML のみ) |
Core のフォールバック/代替手段
「Core のフォールバック/代替手段」という見出しのセクションドキュメント比較に相当する Core の機能はありません。オプションの Artisan リーダーは、インストールされていれば抽出精度を高めますが、必須ではありません。
Enterprise の境界に関する注意
「Enterprise の境界に関する注意」という見出しのセクションこれはコンテンツ変更検出器です。フォレンジックな差分分析器ではなく、証拠用または改ざん帰属のレポートを生成しません。それらの関心事は本モジュールの範囲外です。
公開範囲の境界
「公開範囲の境界」という見出しのセクションこのページは、外部から観測可能な振る舞いと、サポートされる公開 API サーフェスのみを記述します。内部の名前空間パス、ヘルパークラス、メカニズムの表、ランブックのファイル名、チケットの接頭辞は範囲外です。