تخطَّ إلى المحتوى
getnextpdf.com

Pro الإصدار

Diff

يقارن NextPDF\Pro\Diff مستندَي ⁨PDF⁩ ويُبلِّغ عمّا تغيّر. يُنتج المسار السريع فروقًا نصّية محاذاة على مستوى الصفحات؛ ويضيف المسار المُنظَّم كشف تغييرات الصور والبيانات الوصفية ويصوغ النتيجة بصيغة ⁨JSON⁩ أو ⁨HTML⁩.

تُشحَن هذه القدرة في ⁨NextPDF Pro⁩ (nextpdf/pro) وتُفعَّل بمظروف ترخيص من فئة ⁨Pro⁩. النشر بدون ذلك الاستحقاق لا يُحمِّل أصناف هذه القدرة. ‏قارِن الإصدارات واحصل على ترخيص.

لا يحكم أي علم قدرة في وقت التشغيل أصناف ⁨Diff⁩؛ فهي موجودة متى كانت حزمة ⁨Pro⁩ مثبَّتة.

Terminal window
composer require nextpdf/pro:^3

يستخرج PdfDiffer::compare() النصّ لكل صفحة من كل مستند، ويقسّمه إلى أسطر، ويُشغِّل فروق ⁨Myers⁩ على مستوى الأسطر لكل زوج صفحات، مُنتِجًا مناطق مُضافة ومُزالة ومُعدَّلة. يحلّل استخراج النص مُعامِلات إظهار النص في ⁨ISO 32000-2:2020 §9.4⁩ (Tj، TJ، ').

يبني StructuredDiffer على ذلك: يجمع مناطق النص في تغييرات على مستوى الفقرات، ويقارن الصور المُضمَّنة، ويقارن البيانات الوصفية، ويُنتج StructuredDiffResult بملخّص إجمالي. يُسلسِل DiffFormatter تلك النتيجة إلى سلسلة ⁨JSON⁩ نصّية أو شذرة تقرير ⁨HTML⁩.

عندما يكون قارئ ⁨PDF⁩ ⁨Artisan⁩ الاختياري مثبَّتًا، يستخدمه استخراج النص للحصول على محتوى دقيق على مستوى الصفحة؛ وإلا فإن احتياطًا محدودًا على مستوى البايت يمسح دفقات المحتوى مباشرةً.

تقارن أداة الفروق النصَّ والبنية المُستخرَجَين، لا البكسلات المُصيَّرة. المقارنة البنيوية حتمية، ورخيصة، وتُطابِق التغييرات التحريرية التي تهمّ المراجع. أما فرق البكسل فسيُعلِّم بدلًا من ذلك ضوضاء تنعيم الحواف وتلميح الخطوط على أنها محتوى. ولأن ملف ⁨PDF⁩ يخزّن الرسوم الحرفية والتموضع، لا حروفًا جاهزة للقراءة، تُعيد كل مقارنة أولًا بناء النص من دفق المحتوى. تلك الخطوة الاستخراجية هي سبب زيادة قارئ ⁨Artisan⁩ للدقّة، وسبب مقايضة الاحتياط المحدود FlateDecode التغطيةَ بالأمان، وسبب أن الصفحات الممسوحة ضوئيًا تكاد لا تُظهر فروقًا. تبقى محاذاة الصفحات قائمة على الفهرس من أجل القابلية للتنبؤ، بحيث تُقرأ الصفحة المُدرَجة على أنها إزاحة واضحة في ما يليها.

خلفية التصميم: ‏لماذا النص في ملف ⁨PDF⁩ ليس نصًّا حقيقيًا.

  • المُدخَل. بايتات ⁨PDF⁩ خام للمصدر والهدف. مخزن مؤقت لا يبدأ بـ %PDF يثير InvalidArgumentException.
  • المخرَج (المسار السريع).DiffResult بقوائم مناطق added وremoved وmodified إضافةً إلى isIdentical() وhasDifferences() وtotalChanges().
  • المخرَج (المسار المُنظَّم).StructuredDiffResult بفروق الفقرات، وفروق الصور، وتغييرات البيانات الوصفية، وDiffSummary.
  • مخرَج التقرير. يُصدِر 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⁩ الممسوحة ضوئيًا والمؤلَّفة من صور فقط تُنتج فروقًا نصّية قليلة أو معدومة لأنه لا يُجرى أي تعرّف ضوئي على الحروف.
  • بدون قارئ ⁨Artisan⁩ الاختياري، يستخدم الاستخراج الاحتياطَ المحدود؛ والمستندات المضغوطة بشدة قد تُنتج تغطية نصّية مُقلَّصة.

استخراج النص خطّي ببايتات المستند؛ وفروق ⁨Myers⁩ شبه خطّية للمستندات المتشابهة، وتربيعية في أسوأ الحالات لكل زوج صفحات. يحدّ سقف فكّ الضغط الذاكرة. انظر performance_budget.

يستخدم الاحتياط على مستوى البايت مسحًا قائمًا على strpos بدلًا من التعابير النمطية غير المحدودة لتجنّب التراجع الكارثي على ملفات ⁨PDF⁩ المُصطنَعة، ويحدّ مخرَج فكّ الضغط. لا تُنفّذ المقارنة أي سكربتات مُضمَّنة. انظر نموذج أمان ⁨Core⁩.

الادعاءبند المعيارالحالة
تحليل مُعامِل النص Tj للاستخراجISO 32000-2:2020 §9.4مُتحقَّق منه (مجموعة وحدات)
تحليل مُعامِل نص المصفوفة TJ للاستخراجISO 32000-2:2020 §9.4مُتحقَّق منه (مجموعة وحدات)
مخرَج ⁨PDF⁩ بصري بخطّ تصحيح جنبًا إلى جنبغير مدعوم (⁨JSON/HTML⁩ فقط)

لا يوجد مكافئ في ⁨Core⁩ لمقارنة المستندات. يُحسِّن قارئ ⁨Artisan⁩ الاختياري دقّة الاستخراج عند تثبيته لكنه ليس مطلوبًا.

هذا كاشف تغيير محتوى. وهو ليس مُحلِّل فروق جنائيًا ولا يُنتج تقارير استدلالية أو تقارير إسناد عبث؛ تلك الشؤون خارج نطاق هذه الوحدة.

توثّق هذه الصفحة السلوكَ القابل للملاحظة خارجيًا وسطحَ ⁨API⁩ العام المدعوم فقط. أما مسارات فضاء الأسماء الداخلية، وأصناف المساعدة، وجداول الآليات، وأسماء ملفات أدلة التشغيل، وبادئات التذاكر فخارج النطاق.