Salta ai contenuti
getnextpdf.com

Pro edizione

Diff

NextPDF\Pro\Diff confronta due documenti PDF e segnala ciò che è cambiato. Il percorso rapido produce un diff del testo allineato per pagina; il percorso strutturato aggiunge il rilevamento delle modifiche a immagini e metadati e formatta il risultato come JSON o HTML.

Questa funzionalità è inclusa in NextPDF Pro (nextpdf/pro) e si attiva con un envelope di licenza di tier Pro. Un deployment privo di tale entitlement non carica le classi della funzionalità. Confrontare le edizioni e ottenere una licenza.

Nessun flag di capacità a runtime governa le classi del Diff; sono presenti ogni volta che il pacchetto Pro è installato.

Terminal window
composer require nextpdf/pro:^3

PdfDiffer::compare() estrae il testo per pagina da ciascun documento, lo suddivide in righe ed esegue un Myers line diff per ciascuna coppia di pagine, producendo regioni aggiunte, rimosse e modificate. L’estrazione del testo analizza gli operatori di visualizzazione del testo di ISO 32000-2:2020 §9.4 (Tj, TJ, ').

StructuredDiffer si basa su questo: raggruppa le regioni di testo in modifiche a livello di paragrafo, confronta le immagini incorporate, confronta i metadati e produce uno StructuredDiffResult con un riepilogo aggregato. DiffFormatter serializza tale risultato in una stringa JSON o in un frammento di report HTML.

Quando è installato il reader PDF Artisan opzionale, l’estrazione del testo lo usa per un contenuto accurato per pagina; altrimenti un fallback delimitato a livello di byte scansiona direttamente i content stream.

Il differ confronta il testo e la struttura estratti, non i pixel renderizzati. Un confronto strutturale è deterministico, economico e mappa alle modifiche editoriali che interessano a un revisore. Un pixel diff segnalerebbe invece l’antialiasing e il rumore dell’hinting dei font come contenuto. Poiché un PDF memorizza glifi e posizionamento, non caratteri pronti da leggere, ogni confronto ricostruisce prima il testo dal content stream. Quel passo di estrazione è il motivo per cui il reader Artisan affina l’accuratezza, il motivo per cui il fallback delimitato FlateDecode scambia la copertura con la sicurezza e il motivo per cui le pagine acquisite tramite scanner producono un diff minimo. L’allineamento delle pagine resta basato sull’indice per prevedibilità, così una pagina inserita si legge come un chiaro spostamento a valle.

Contesto di progettazione: Perché il testo in un PDF non è davvero testo.

  • Input. Byte PDF grezzi per sorgente e destinazione. Un buffer che non inizia con %PDF solleva InvalidArgumentException.
  • Output (percorso rapido). DiffResult con elenchi di regioni added, removed, modified oltre a isIdentical(), hasDifferences(), totalChanges().
  • Output (percorso strutturato). StructuredDiffResult con diff dei paragrafi, diff delle immagini, modifiche ai metadati e un DiffSummary.
  • Output del report. DiffFormatter emette una stringa JSON o un frammento HTML. Non produce un PDF redline visivo affiancato.
  • Limiti delle risorse. La dimensione decompressa del content stream è limitata per difendersi dalle decompression bomb; lo scanner a livello di byte evita il backtracking catastrofico delle regex su input costruito ad arte.
  • Determinismo. Per input identici, le regioni del diff e l’output formattato sono stabili.
TypeKindKey members
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 classtext diff, paragraphs, images, metadata changes, summary
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);
}
  • Il diff è allineato per pagina in base all’indice. L’inserimento di una pagina in anticipo sposta tutte le pagine successive e segnala ampie modifiche a valle — questo è il comportamento atteso per un confronto allineato per indice.
  • Il confronto delle immagini rileva immagini incorporate aggiunte, rimosse e modificate; non è un diff visivo percettivo e non esegue il rendering pixel delle pagine.
  • I PDF acquisiti tramite scanner e composti da sole immagini producono un diff del testo scarso o nullo perché non viene eseguito alcun OCR.
  • Senza il reader Artisan opzionale, l’estrazione usa il fallback delimitato; i documenti fortemente compressi potrebbero produrre una copertura del testo ridotta.

L’estrazione del testo è lineare rispetto ai byte del documento; il Myers diff è quasi lineare per documenti simili e quadratico nel caso peggiore per ciascuna coppia di pagine. Il limite di decompressione delimita la memoria. Vedere performance_budget.

Il fallback a livello di byte usa una scansione basata su strpos anziché regex non delimitate per evitare il backtracking catastrofico su PDF costruiti ad arte, e delimita l’output della decompressione. L’operazione di diff non esegue script incorporati. Vedere il modello di sicurezza del Core.

ClaimSpec clauseStatus
Tj text operator parsed for extractionISO 32000-2:2020 §9.4Verified (unit suite)
TJ array text operator parsed for extractionISO 32000-2:2020 §9.4Verified (unit suite)
Visual side-by-side redline PDF outputNot supported (JSON/HTML only)

Non esiste alcun equivalente Core per il confronto dei documenti. Il reader Artisan opzionale migliora l’accuratezza dell’estrazione quando installato, ma non è richiesto.

Questo è un rilevatore di modifiche al contenuto. Non è un analizzatore forense delle differenze e non produce report probatori o di attribuzione delle manomissioni; tali temi sono fuori ambito per questo modulo.

Questa pagina documenta solo il comportamento osservabile dall’esterno e la superficie pubblica dell’API supportata. I percorsi di namespace interni, le classi helper, le tabelle dei meccanismi, i nomi dei file dei runbook e i prefissi dei ticket sono fuori ambito.