コンテンツにスキップ
getnextpdf.com

Pro エディション

差分

NextPDF\Pro\Diff は、2 つの PDF ドキュメントを比較し、何が変わったかをレポートします。クイックパスはページ整列されたテキスト差分を生成し、構造化パスは画像とメタデータの変更検出を追加して、結果を JSON または HTML として整形します。

この機能は NextPDF Pronextpdf/pro)に同梱され、Pro ティアのライセンスエンベロープで有効になります。そのエンタイトルメントがないデプロイメントでは、この機能のクラスは読み込まれません。エディションを比較してライセンスを取得する

差分のクラスをゲートするランタイムの機能フラグはありません。Pro パッケージがインストールされていれば常に存在します。

Terminal window
composer require nextpdf/pro:^3

PdfDiffer::compare() は、各ドキュメントからページごとにテキストを抽出して行に分割し、ページのペアごとに Myers の行差分を実行して、追加・削除・変更された領域を生成します。テキスト抽出は、ISO 32000-2:2020 §9.4 のテキスト表示演算子(TjTJ')を解析します。

StructuredDiffer はその上に構築されます。テキスト領域を段落レベルの変更にグループ化し、埋め込み画像を比較し、メタデータを比較し、集約サマリーを持つ StructuredDiffResult を生成します。DiffFormatter は、その結果を JSON 文字列または HTML レポートフラグメントにシリアライズします。

オプションの Artisan PDF リーダーがインストールされている場合、テキスト抽出はそれを用いてページ単位で正確な内容を取得します。そうでない場合は、上限付きのバイトレベルのフォールバックがコンテンツストリームを直接スキャンします。

この差分機能は、レンダリングされたピクセルではなく、抽出されたテキストと構造を比較します。構造的な比較は決定的で低コストであり、レビュー担当者が気にする編集上の変更に対応づけられます。ピクセル差分では、アンチエイリアシングやフォントヒンティングのノイズをコンテンツとして誤って検出してしまいます。PDF は読み取り可能な文字ではなくグリフと位置情報を格納しているため、すべての比較はまずコンテンツストリームからテキストを再構築します。この抽出ステップこそが、Artisan リーダーが精度を高める理由であり、上限付きの FlateDecode フォールバックがカバレッジと引き換えに安全性を取る理由であり、スキャンされたページがほとんど差分にならない理由です。ページの整列は予測可能性のためにインデックスベースを維持しており、挿入されたページは明確な下流側のずれとして読み取られます。

設計の背景: PDF のテキストは本当のテキストではない理由

  • 入力。 ソースとターゲットの生 PDF バイト。%PDF で始まらないバッファは InvalidArgumentException を発生させます。
  • 出力(クイックパス)。 addedremovedmodified の領域リストと、isIdentical()hasDifferences()totalChanges() を持つ DiffResult
  • 出力(構造化パス)。 段落差分、画像差分、メタデータ変更、DiffSummary を持つ StructuredDiffResult
  • レポート出力。 DiffFormatter は JSON 文字列または HTML フラグメントを出力します。視覚的な左右並列レッドライン PDF は生成しません。
  • リソースの上限。 解凍後のコンテンツストリームサイズは、解凍爆弾を防ぐために上限が設けられています。バイトレベルのスキャナーは、細工された入力に対する破滅的な正規表現バックトラッキングを回避します。
  • 決定性。 同一の入力に対して、差分領域と整形された出力は安定しています。
種別主なメンバー
NextPDF\Pro\Diff\PdfDifferfinal classstatic compare(string $sourcePdf, string $targetPdf): DiffResult, static compareTexts(array $sourcePages, array $targetPages): DiffResult, static extractText(string $contentStream): string
NextPDF\Pro\Diff\StructuredDifferfinal class__construct(?ImageDiffer $imageDiffer = null, ?MetadataDiffer $metadataDiffer = null), compare(string $sourcePdf, string $targetPdf): StructuredDiffResult
NextPDF\Pro\Diff\DiffFormatterfinal classtoJson(StructuredDiffResult $result): string, toHtml(StructuredDiffResult $result): string
NextPDF\Pro\Diff\DiffResultfinal readonly classarray $added, array $removed, array $modified, isIdentical(): bool, hasDifferences(): bool, totalChanges(): int
NextPDF\Pro\Diff\StructuredDiffResultfinal readonly classテキスト差分、段落、画像、メタデータ変更、サマリー
NextPDF\Pro\Diff\DiffTypeenumAdded, 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 の機能はありません。オプションの Artisan リーダーは、インストールされていれば抽出精度を高めますが、必須ではありません。

これはコンテンツ変更検出器です。フォレンジックな差分分析器ではなく、証拠用または改ざん帰属のレポートを生成しません。それらの関心事は本モジュールの範囲外です。

このページは、外部から観測可能な振る舞いと、サポートされる公開 API サーフェスのみを記述します。内部の名前空間パス、ヘルパークラス、メカニズムの表、ランブックのファイル名、チケットの接頭辞は範囲外です。