Lewati ke konten
getnextpdf.com

Pro edisi

Diff — Referensi Mendalam

Halaman ini adalah referensi tingkat kontrak untuk modul diff NextPDF Pro, NextPDF\Pro\Diff. Modul ini membandingkan dua dokumen PDF dan melaporkan perubahan teks, gambar, dan metadata. PdfDiffer menghasilkan diff baris Myers yang selaras per halaman. StructuredDiffer menambahkan pengelompokan paragraf, perbandingan gambar, dan perbandingan metadata. DiffFormatter menserialisasi hasil terstruktur ke JSON atau fragmen HTML. Halaman ini menyatakan API publik, kontrak perilaku yang dapat diamati, batas sumber daya, dan mode kegagalan. Penyiapan berorientasi tugas dan contoh tersedia di halaman kapabilitas Diff.

Kapabilitas ini hadir dalam NextPDF Pro (nextpdf/pro) dan aktif dengan envelope lisensi tingkat Pro. Deployment tanpa hak tersebut tidak memuat kelas-kelas kapabilitas ini. Bandingkan edisi dan dapatkan lisensi.

Tidak ada flag kapabilitas runtime yang menggerbang modul ini. Kelas-kelas diff dapat digunakan setiap kali nextpdf/pro terinstal dan berlisensi.

SimbolParameterPerilaku defaultMengembalikanMelempar atau gagal denganCatatan
PdfDiffer::compare()string $sourcePdf, string $targetPdfMengekstraksi teks per halaman, lalu men-diff halaman i sumber terhadap halaman i targetDiffResultInvalidArgumentException ketika sebuah buffer tidak memiliki header %PDF atau pembaca opsional gagal mengurai; OverflowException pada batas sumber dayaTitik masuk statis
PdfDiffer::compareTexts()array $sourcePages, array $targetPages (list<string> masing-masing)Men-diff teks halaman yang telah diekstraksi sebelumnya, melewati ekstraksiDiffResultOverflowException pada batas sumber dayaStatis; gunakan ketika teks sudah tersedia
PdfDiffer::extractText()string $contentStreamMengurai operator penampil teks dari satu content stream mentahstring— (toleran kesalahan; masukan yang tidak dapat diurai menghasilkan string kosong)Statis
StructuredDiffer::__construct()?ImageDiffer $imageDiffer = null, ?MetadataDiffer $metadataDiffer = nullArgumen null mengonstruksi differ defaultInjeksi konstruktor untuk pengujian
StructuredDiffer::compare()string $sourcePdf, string $targetPdfMenjalankan perbandingan teks, paragraf, gambar, dan metadata, lalu membangun ringkasanStructuredDiffResultMeneruskan InvalidArgumentException dan OverflowException dari jalur teksOrkestrator atas seluruh modul
DiffFormatter::toJson()StructuredDiffResult $resultDokumen JSON yang diformat rapistringJsonException ketika encoding gagal
DiffFormatter::toHtml()StructuredDiffResult $resultFragmen HTML dengan bagian ringkasan, paragraf, dan metadata; nilai teks di-escape sebagai entitasstringHanya fragmen, bukan dokumen lengkap
DiffFormatter::toArray()StructuredDiffResult $resultArray serialisasi yang mendukung toJson()array<string, mixed>Kunci snake_case yang stabil
ImageDiffer::diff()string $sourcePdf, string $targetPdfMeng-hash image XObject dan melaporkan gambar yang ditambahkan, dihapus, dan dimodifikasilist<ImageDiff>— (struktur yang tidak dapat didekode dilewati secara fail-closed)Identitas adalah bucket halaman ditambah nomor objek
MetadataDiffer::diff()string $sourcePdf, string $targetPdfMembandingkan delapan field /Info (Title, Author, Subject, Keywords, Creator, Producer, CreationDate, ModDate)list<MetadataChange>— (tidak pernah melempar pada masukan yang tidak sesuai)Nilai dibandingkan sebagai string yang telah didekode
DiffEngine::diff()array $sourceLines, array $targetLines, int $pageIndex = 0, int $maxLines = 10000Diff baris Myers atas dua daftar barislist<DiffRegion>OverflowException ketika total baris melebihi $maxLines atau jarak edit melebihi batas terikat-memoriStatis; penghasil wilayah untuk semua jalur teks
TextExtractor::fromContentStream()string $contentStreamMenokenisasi stream dan menjalankan mesin keadaan tekslist<TextBlock>Statis
TextExtractor::fromOperations()array $operations (list<ContentStreamOp>)Menjalankan mesin keadaan teks atas operasi yang telah diurai sebelumnyalist<TextBlock>Statis
ContentStreamParser::parse()konstruktor menerima string $dataMenokenisasi operator dan operan; melewati dictionary dan komentar; toleran kesalahanlist<ContentStreamOp>Byte yang tidak dikenali dilewati, tidak pernah fatal
ContentStreamOpstring $operator, list<mixed> $operandsValue object operasi readonly; isTextOp() mengklasifikasikan operator terkait teks
DiffResultlist<DiffRegion> $regions, int $sourcePagesCount, int $targetPagesCountMengelompokkan wilayah ke $added, $removed, $modified; mengekspos isIdentical(), hasDifferences(), totalChanges()Readonly; wilayah Unchanged hanya tetap berada di $regions
StructuredDiffResultdiff teks, paragraf, gambar, perubahan metadata, ringkasanHasil agregat; hasDifferences(), isIdentical() mendelegasikan ke ringkasanReadonly
DiffSummaryjumlah per kategori ditambah jumlah halamanhasDifferences() dan totalChanges() atas jumlah teks, gambar, dan metadataReadonly
DiffRegionDiffType $type, string $text, int $pageIndex, int $lineIndex, ?string $counterpartText = nullSatu perubahan tingkat baris$counterpartText tetap null pada mesin yang dirilis
ParagraphDifftipe, teks, indeks halaman, baris awal/akhir, wilayahWilayah bertipe sama yang berurutan pada satu halaman; lineCount()Readonly
ImageDifftipe, indeks halaman, hash sumber, hash target, id objekSatu entri perubahan gambarHash berupa string kosong pada sisi yang tidak ada
MetadataChangestring $field, ?string $sourceValue, ?string $targetValueSatu perubahan field; isAdded(), isRemoved(), isModified()null berarti field tidak ada
TextBlockteks, x, y, nama font, ukuran font, indeks barisSatu text run yang diekstraksi dengan posisi perkiraanReadonly
DiffTypeenum: Added, Removed, Modified, UnchangedKlasifikasi perubahan berbasis string untuk teksLihat catatan Modified di kontrak perilaku
ImageDiffTypeenum: Added, Removed, Modified, UnchangedKlasifikasi perubahan berbasis string untuk gambar
public static function compare(string $sourcePdf, string $targetPdf): DiffResult
public static function compareTexts(array $sourcePages, array $targetPages): DiffResult
public static function extractText(string $contentStream): string
public function __construct(
?ImageDiffer $imageDiffer = null,
?MetadataDiffer $metadataDiffer = null,
)
public function compare(string $sourcePdf, string $targetPdf): StructuredDiffResult
public function toJson(StructuredDiffResult $result): string
public function toHtml(StructuredDiffResult $result): string
public function toArray(StructuredDiffResult $result): array
public static function diff(
array $sourceLines,
array $targetLines,
int $pageIndex = 0,
int $maxLines = self::MAX_DIFF_LINES,
): array

PdfDiffer::compare() mengekstraksi teks per halaman, lalu men-diff halaman i sumber terhadap halaman i target. Ketika jumlah halaman berbeda, sisi yang hilang diperlakukan sebagai teks kosong untuk halaman yang berlebih. Dalam tiap pasangan halaman, teks dipecah pada baris baru dan diff baris Myers berjalan per halaman. Mesin memancarkan wilayah Added, Removed, dan Unchanged. Sebuah baris yang berubah muncul sebagai wilayah Removed ditambah Added; mesin yang dirilis tidak pernah memancarkan wilayah teks Modified. Kasus Modified dan bucket DiffResult::$modified melayani hasil yang dikonstruksi pemanggil, karena konstruktor DiffResult bersifat publik. totalChanges() menghitung wilayah added, removed, dan modified; wilayah unchanged dikecualikan.

Ekstraksi memiliki dua jalur:

  • Pembaca Artisan opsional hadir. Ketika kelas NextPDF\Parser\PdfReader opsional terinstal, content stream halaman dibaca melaluinya untuk teks yang akurat per halaman. Jumlah halaman pada trailer menggerakkan loop. Sebuah halaman yang gagal dibaca menyumbangkan teks kosong alih-alih membatalkan perbandingan.
  • Cadangan. Pemindai tingkat byte berbatas menemukan pasangan stream/endstream dengan strpos, meng-inflate data FlateDecode dengan batas keluaran keras 50 MB, dan membalikkan filter prediktor PNG ketika stream dictionary memintanya melalui /DecodeParms sesuai ISO 32000-2:2020 §7.4.4.4. Prediktor yang cacat atau tidak didukung membiarkan byte terdekode tidak berubah. Cadangan menggabungkan semua teks yang dipulihkan ke dalam satu bucket halaman, sehingga penyelarasan tingkat halaman hanya akurat per halaman pada jalur pembaca.

Kedua jalur mengurai operator penampil teks §9.4 Tj, TJ, dan '. Mesin keadaan melacak BT/ET, Tm (hanya origin), Td/TD, T*, dan Tf.

StructuredDiffer::compare() menjalankan diff teks, mengelompokkan wilayah bertipe sama yang berurutan pada halaman yang sama menjadi paragraf (termasuk run unchanged), lalu menjalankan perbandingan gambar dan metadata serta merangkai sebuah DiffSummary. Jumlah paragraf dalam ringkasan hanya mencakup paragraf added, removed, dan modified.

Perbandingan gambar mengenumerasi objek PDF secara struktural. Rentang badan sebuah stream diatur oleh entri /Length-nya sesuai §7.3.8.2, sehingga byte biner yang sekadar menyerupai sintaks objek tidak pernah terdaftar sebagai objek fantom. Object stream terkompresi (/Type /ObjStm) didekode sesuai §7.5.7 agar image XObject yang bersarang di dalamnya terlihat. Setiap gambar yang terdeteksi di-hash berdasarkan konten dengan fungsi non-kriptografis xxh128; identitasnya adalah pasangan bucket halaman dan nomor objek. Gambar tanpa halaman pemilik dalam urutan stream diatribusikan ke halaman 0.

Perbandingan metadata meresolusi dictionary /Info yang sebenarnya melalui trailer bila memungkinkan, sehingga token field umpan di dalam content stream tidak keliru dianggap sebagai metadata dokumen. Nilai field didekode sebagai string PDF: bentuk literal sesuai §7.3.4.2 dan bentuk heksadesimal sesuai §7.3.4.3. Tanpa trailer yang dapat diresolusi, pencarian jatuh kembali ke seluruh masukan. Tanggal dibandingkan sebagai string yang telah didekode, bukan timestamp yang telah diurai.

DiffFormatter::toJson() mengembalikan JSON yang diformat rapi dan meng-encode dengan JSON_THROW_ON_ERROR, sehingga kegagalan encoding memunculkan JsonException alih-alih mengembalikan false. toHtml() mengembalikan fragmen <div class="nextpdf-diff">; teks paragraf dan nilai metadata melewati escaping entitas HTML. Tidak ada keluaran PDF redline berdampingan secara visual. Untuk masukan yang identik, wilayah dan keluaran terformat bersifat deterministik.

  • Penyelarasan halaman bersifat posisional. Satu halaman yang disisipkan atau dihapus menggeser penyelarasan untuk semua halaman berikutnya dan menggelembungkan jumlah perubahan di hilir.
  • Pada jalur ekstraksi cadangan, semua teks mendarat di indeks halaman 0. Men-diff dokumen yang diekstraksi pembaca terhadap ekspektasi dari jalur cadangan menghasilkan atribusi halaman yang berbeda.
  • Buffer sumber atau target yang tidak diawali %PDF gagal dengan InvalidArgumentException sebelum perbandingan apa pun.
  • Lebih dari 10,000 total baris dalam satu pasangan halaman gagal dengan OverflowException (batas jumlah baris).
  • Dua teks halaman yang berbagi terlalu sedikit baris gagal dengan OverflowException begitu jarak edit Myers melebihi batas terikat-memori. Revisi yang sah berbagi sebagian besar baris dan tetap tidak terpengaruh; masukan adversarial dengan kesamaan rendah memicu batas tersebut.
  • Keluaran stream cadangan terdekompresi yang lebih besar dari 50 MB gagal dengan OverflowException (batas decompression bomb). Pemindai menggunakan strpos, bukan regex tak berbatas, sehingga masukan yang dirancang tidak dapat memicu backtracking katastrofik.
  • Operator penampil teks " ditokenisasi tetapi tidak menghasilkan text block pada 3.1.0; teks yang hanya ditampilkan melalui " tidak berpartisipasi dalam diff.
  • PDF hasil pindaian yang hanya berisi gambar menghasilkan sedikit atau tanpa diff teks. Tidak ada OCR yang berjalan.
  • Deteksi perubahan gambar bersifat struktural, bukan perseptual. Ia tidak me-rasterisasi halaman, dan sebuah gambar yang di-encode ulang dengan piksel identik dilaporkan sebagai modified ketika byte-nya berbeda.
  • Sebuah gambar yang bucket halaman atau nomor objeknya berubah antar revisi dilaporkan sebagai pasangan removed-plus-added, bukan sebagai modified.
  • Object stream yang terkompresi dengan filter selain FlateDecode dilewati secara fail-closed; gambar anggotanya tidak dibandingkan.
  • Tidak ada operasi kriptografis yang terjadi di modul ini, sehingga tidak ada perilaku spesifik mode FIPS. Hash gambar hanya untuk deteksi perubahan dan tidak membawa bobot integritas atau pembuktian.
KlaimStandarKlausul
Operator penampil teks Tj dan TJ diurai untuk ekstraksiISO 32000-2:2020§9.4
Data stream cadangan dimulai setelah CRLF atau LF yang mengikuti kata kunci streamISO 32000-2:2020§7.3.8.1
Rentang stream pemindaian gambar diatur oleh entri /Length pada dictionaryISO 32000-2:2020§7.3.8.2
Anggota object stream ditemukan melalui tabel pasangan /N dan offset /FirstISO 32000-2:2020§7.5.7
Pembalikan prediktor PNG mengikuti parameter Predictor pada /DecodeParmsISO 32000-2:2020§7.4.4.4
Nilai metadata mendekode bentuk string literal dan heksadesimalISO 32000-2:2020§7.3.4.2, §7.3.4.3
Keluaran PDF redline berdampingan secara visualTidak didukung (hanya JSON/HTML)

Semua klausul diparafrasekan; NextPDF tidak mereproduksi teks normatif. Ini adalah pernyataan kapabilitas, bukan sertifikasi; NextPDF tidak memegang sertifikasi apa pun dan tidak memberikan sertifikasi apa pun. Pemulihan teks merekonstruksi teks baris dari operator penampil teks. Ia tidak menjalankan mesin keadaan teks §9.4 lengkap, sehingga diff berada di tingkat konten, bukan tingkat geometri.

  • Ketersediaan dalam paket Pro: PdfDiffer, DiffEngine, TextExtractor, dan value object-nya sejak 1.8.0; StructuredDiffer, DiffFormatter, ImageDiffer, MetadataDiffer, dan value object-nya sejak 2.2.0. Semuanya terkini di nextpdf/pro 3.1.0.
  • Utamakan PdfDiffer::compareTexts() ketika teks halaman sudah tersedia; ia melewati ekstraksi dan mode kegagalannya sepenuhnya.
  • Pembaca Artisan opsional meningkatkan akurasi ekstraksi dan atribusi halaman. Ia dideteksi saat runtime dan tidak pernah diwajibkan.
  • Tangkap OverflowException saat men-diff masukan tak tepercaya; batas-batas tersebut adalah penolakan fail-closed yang disengaja, bukan kesalahan transien.
  • DiffFormatter::toHtml() memancarkan nama kelas (diff-added, diff-removed, diff-modified, diff-unchanged) tetapi tanpa stylesheet; sediakan CSS Anda sendiri.
  • Konstruksi StructuredDiffer dengan differ stub dalam pengujian untuk mengisolasi jalur teks dari pemindaian gambar dan metadata.

Halaman ini hanya mendokumentasikan perilaku yang dapat diamati secara eksternal dan permukaan API publik yang didukung. Jalur namespace internal, kelas helper, tabel mekanisme, nama file runbook, dan prefiks tiket berada di luar cakupan.