Ga naar inhoud
getnextpdf.com

Pro editie

Diff

NextPDF\Pro\Diff vergelijkt twee PDF-documenten en rapporteert wat er is gewijzigd. Het snelle pad produceert een pagina-uitgelijnde tekst-diff; het gestructureerde pad voegt detectie van wijzigingen in afbeeldingen en metadata toe en maakt het resultaat op als JSON of HTML.

Deze functie zit in NextPDF Pro (nextpdf/pro) en activeert met een licentie-envelop op Pro-niveau. Een deployment zonder die entitlement laadt de klassen van de functie niet. Vergelijk edities en vraag een licentie aan.

Geen runtime-mogelijkheidsvlag bewaakt de Diff-klassen; ze zijn aanwezig zodra het Pro-pakket is geïnstalleerd.

Terminal window
composer require nextpdf/pro:^3

PdfDiffer::compare() extraheert per pagina tekst uit elk document, splitst deze op in regels en voert per paginapaar een Myers-regel-diff uit, wat toegevoegde, verwijderde en gewijzigde regio’s oplevert. Tekstextractie parseert de tekstweergave- operatoren van ISO 32000-2:2020 §9.4 (Tj, TJ, ').

StructuredDiffer bouwt daarop voort: deze groepeert tekstregio’s tot wijzigingen op alinea-niveau, vergelijkt ingebedde afbeeldingen, vergelijkt metadata en produceert een StructuredDiffResult met een geaggregeerde samenvatting. DiffFormatter serialiseert dat resultaat naar een JSON-string of een HTML-rapportfragment.

Wanneer de optionele Artisan PDF-reader is geïnstalleerd, gebruikt tekstextractie deze voor pagina-nauwkeurige inhoud; anders scant een begrensde fallback op byteniveau contentstreams rechtstreeks.

De differ vergelijkt geëxtraheerde tekst en structuur, niet gerenderde pixels. Een structurele vergelijking is deterministisch, goedkoop en sluit aan op de redactionele wijzigingen waar een beoordelaar om geeft. Een pixel-diff zou daarentegen antialiasing en font-hinting-ruis als inhoud markeren. Omdat een PDF glyphs en positionering opslaat, en niet kant-en-klare leesbare tekens, reconstrueert elke vergelijking eerst tekst uit de contentstream. Die extractiestap is waarom de Artisan-reader de nauwkeurigheid aanscherpt, waarom de begrensde FlateDecode-fallback dekking inruilt voor veiligheid, en waarom gescande pagina’s nauwelijks diffen. Pagina-uitlijning blijft op index gebaseerd voor voorspelbaarheid, zodat een ingevoegde pagina leest als een duidelijke stroomafwaartse verschuiving.

Ontwerpachtergrond: Waarom de tekst in een PDF niet echt tekst is.

  • Invoer. Ruwe PDF-bytes voor bron en doel. Een buffer die niet begint met %PDF werpt InvalidArgumentException.
  • Uitvoer (snelle pad). DiffResult met de regiolijsten added, removed, modified plus isIdentical(), hasDifferences(), totalChanges().
  • Uitvoer (gestructureerde pad). StructuredDiffResult met alinea-diffs, afbeeldings-diffs, metadatawijzigingen en een DiffSummary.
  • Rapportuitvoer. DiffFormatter zendt een JSON-string of een HTML-fragment uit. Deze produceert geen visuele zij-aan-zij-redline-PDF.
  • Resourcegrenzen. De gedecomprimeerde contentstreamgrootte is begrensd ter bescherming tegen decompressiebommen; de scanner op byteniveau vermijdt catastrofale regex-backtracking op geprepareerde invoer.
  • Determinisme. Voor identieke invoer zijn de diff-regio’s en de opgemaakte uitvoer stabiel.
TypeSoortBelangrijkste leden
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 classtekst-diff, alinea’s, afbeeldingen, metadatawijzigingen, samenvatting
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);
}
  • De diff is pagina-uitgelijnd op index. Een pagina vroeg invoegen verschuift alle latere pagina’s en rapporteert grote stroomafwaartse wijzigingen — dit is verwacht voor een index-uitgelijnde vergelijking.
  • Afbeeldingsvergelijking detecteert toegevoegde, verwijderde en gewijzigde ingebedde afbeeldingen; het is geen perceptuele visuele diff en rendert geen pagina’s pixel voor pixel.
  • Gescande alleen-afbeelding-PDF’s produceren weinig of geen tekst-diff omdat er geen OCR wordt uitgevoerd.
  • Zonder de optionele Artisan-reader gebruikt extractie de begrensde fallback; sterk gecomprimeerde documenten kunnen een verminderde tekstdekking opleveren.

Tekstextractie is lineair in de documentbytes; de Myers-diff is bijna-lineair voor vergelijkbare documenten en kwadratisch in het slechtste geval per pagina- paar. De decompressielimiet begrenst het geheugen. Zie performance_budget.

De fallback op byteniveau gebruikt strpos-gebaseerd scannen in plaats van onbegrensde regex om catastrofale backtracking op geprepareerde PDF’s te vermijden, en begrenst de decompressie-uitvoer. Diffen voert geen ingebedde scripts uit. Zie het Core-beveiligingsmodel.

ClaimSpec-clausuleStatus
Tj-tekstoperator geparseerd voor extractieISO 32000-2:2020 §9.4Geverifieerd (unit suite)
TJ-array-tekstoperator geparseerd voor extractieISO 32000-2:2020 §9.4Geverifieerd (unit suite)
Visuele zij-aan-zij-redline-PDF-uitvoerNiet ondersteund (alleen JSON/HTML)

Er bestaat geen Core-equivalent voor documentvergelijking. De optionele Artisan- reader verbetert de extractienauwkeurigheid wanneer geïnstalleerd, maar is niet vereist.

Dit is een detector van inhoudswijzigingen. Het is geen forensische verschilanalysator en produceert geen bewijskrachtige of manipulatieattributierapporten; die aangelegenheden vallen buiten het bereik van deze module.

Deze pagina documenteert alleen extern waarneembaar gedrag en het ondersteunde publieke API-oppervlak. Interne namespace-paden, helper-klassen, mechanismetabellen, runbook-bestandsnamen en ticketprefixen vallen buiten het bereik.