Pro الإصدار
Diff — مرجع متعمّق
لمحة سريعة
قسم بعنوان «لمحة سريعة»هذه الصفحة هي المرجع على مستوى العقد لوحدة diff في NextPDF Pro، وهي NextPDF\Pro\Diff. تقارن هذه الوحدة مستندَي PDF وتُبلّغ عن تغييرات النص والصور والبيانات الوصفية. ينتج PdfDiffer مقارنة أسطر بخوارزمية Myers مُحاذاة على مستوى الصفحات. يضيف StructuredDiffer تجميع الفقرات ومقارنة الصور ومقارنة البيانات الوصفية. يُسلسِل DiffFormatter النتيجة المُهيكلة إلى JSON أو جزء HTML. تُبيّن هذه الصفحة واجهة برمجة التطبيقات العامة، وعقد السلوك القابل للملاحظة، وحدود الموارد، وأنماط الإخفاق. يوجد الإعداد الموجّه للمهام والعيّنات في صفحة قدرة Diff.
التوفّر والترخيص
قسم بعنوان «التوفّر والترخيص»تُشحن هذه القدرة ضمن NextPDF Pro (nextpdf/pro) وتُفعَّل بمظروف ترخيص من فئة Pro. لا يُحمِّل أي نشر يفتقر إلى ذلك الاستحقاق أصنافَ هذه القدرة. قارن بين الإصدارات واحصل على ترخيص.
لا توجد راية قدرة زمن التشغيل تحجب هذه الوحدة. أصناف diff قابلة للاستخدام متى ما كان nextpdf/pro مُثبَّتًا ومُرخَّصًا.
سطح واجهة برمجة التطبيقات العامة
قسم بعنوان «سطح واجهة برمجة التطبيقات العامة»| الرمز | المعامِلات | السلوك الافتراضي | القيمة المُعادة | يرمي أو يُخفق بـ | ملاحظات |
|---|---|---|---|---|---|
PdfDiffer::compare() | string $sourcePdf, string $targetPdf | يستخرج نص كل صفحة، ثم يقارن الصفحة i من المصدر بالصفحة i من الهدف | DiffResult | InvalidArgumentException عندما يفتقر مخزن مؤقت إلى ترويسة %PDF أو يُخفق القارئ الاختياري في التحليل؛ OverflowException عند بلوغ حد مورد | نقطة دخول ساكنة (static) |
PdfDiffer::compareTexts() | array $sourcePages, array $targetPages (list<string> لكلٍّ منهما) | يقارن نصوص الصفحات المُستخرَجة مسبقًا، متجاوزًا الاستخراج | DiffResult | OverflowException عند بلوغ حد مورد | ساكنة؛ استخدمها عندما يكون النص متوفّرًا بالفعل |
PdfDiffer::extractText() | string $contentStream | يحلّل مُعامِلات إظهار النص من مجرى محتوى خام واحد | string | — (متسامح مع الأخطاء؛ المُدخل غير القابل للتحليل يُنتج سلسلة فارغة) | ساكنة |
StructuredDiffer::__construct() | ?ImageDiffer $imageDiffer = null, ?MetadataDiffer $metadataDiffer = null | الوسائط null تُنشئ المقارِنات الافتراضية | — | — | حقن عبر المُنشئ لأغراض الاختبار |
StructuredDiffer::compare() | string $sourcePdf, string $targetPdf | يُجري مقارنة النص والفقرات والصور والبيانات الوصفية، ثم يبني ملخّصًا | StructuredDiffResult | يُمرِّر InvalidArgumentException وOverflowException من مسار النص | المنسّق عبر الوحدة بأكملها |
DiffFormatter::toJson() | StructuredDiffResult $result | مستند JSON منسّق للطباعة | string | JsonException عند إخفاق الترميز | — |
DiffFormatter::toHtml() | StructuredDiffResult $result | جزء HTML يضم أقسام الملخّص والفقرات والبيانات الوصفية؛ تُهرَّب قيم النص ككيانات | string | — | جزء فقط، وليس مستندًا كاملًا |
DiffFormatter::toArray() | StructuredDiffResult $result | مصفوفة التسلسل التي يعتمد عليها toJson() | array<string, mixed> | — | مفاتيح snake_case ثابتة |
ImageDiffer::diff() | string $sourcePdf, string $targetPdf | يُجزّئ (hash) كائنات الصور XObjects ويُبلّغ عن الصور المُضافة والمحذوفة والمعدّلة | list<ImageDiff> | — (البنى غير القابلة لفكّ الترميز تُتجاوز على نحوٍ مُغلَق عند الإخفاق) | الهوية هي دلو الصفحة إضافةً إلى رقم الكائن |
MetadataDiffer::diff() | string $sourcePdf, string $targetPdf | يقارن ثمانية حقول /Info (Title, Author, Subject, Keywords, Creator, Producer, CreationDate, ModDate) | list<MetadataChange> | — (لا يرمي أبدًا عند مُدخل غير مطابق) | تُقارَن القيم كسلاسل مفكوكة الترميز |
DiffEngine::diff() | array $sourceLines, array $targetLines, int $pageIndex = 0, int $maxLines = 10000 | مقارنة أسطر Myers على قائمتَي أسطر | list<DiffRegion> | OverflowException عندما تتجاوز الأسطر المجمّعة $maxLines أو تتجاوز مسافة التحرير الحد المقيَّد بالذاكرة | ساكنة؛ مُنتِج المناطق لجميع مسارات النص |
TextExtractor::fromContentStream() | string $contentStream | يُرمِّز المجرى إلى وحدات ويُشغّل آلة حالة النص | list<TextBlock> | — | ساكنة |
TextExtractor::fromOperations() | array $operations (list<ContentStreamOp>) | يُشغّل آلة حالة النص على العمليات المُحلّلة مسبقًا | list<TextBlock> | — | ساكنة |
ContentStreamParser::parse() | يأخذ المُنشئ string $data | يُرمِّز المُعامِلات والمعطيات إلى وحدات؛ يتخطى القواميس والتعليقات؛ متسامح مع الأخطاء | list<ContentStreamOp> | — | تُتخطى البايتات غير المُتعرَّف عليها، ولا تكون قاتلة أبدًا |
ContentStreamOp | string $operator, list<mixed> $operands | كائن قيمة عملية للقراءة فقط؛ isTextOp() يُصنّف المُعامِلات المتعلقة بالنص | — | — | — |
DiffResult | list<DiffRegion> $regions, int $sourcePagesCount, int $targetPagesCount | يوزّع المناطق في $added و$removed و$modified؛ يكشف isIdentical() وhasDifferences() وtotalChanges() | — | — | للقراءة فقط؛ مناطق Unchanged تبقى في $regions فقط |
StructuredDiffResult | مقارنة النص، والفقرات، والصور، وتغييرات البيانات الوصفية، والملخّص | نتيجة مُجمَّعة؛ hasDifferences() وisIdentical() تُفوِّضان إلى الملخّص | — | — | للقراءة فقط |
DiffSummary | أعداد لكل فئة إضافةً إلى أعداد الصفحات | hasDifferences() وtotalChanges() على أعداد النص والصور والبيانات الوصفية | — | — | للقراءة فقط |
DiffRegion | DiffType $type, string $text, int $pageIndex, int $lineIndex, ?string $counterpartText = null | تغيير واحد على مستوى السطر | — | — | $counterpartText يبقى null في المحرك المُشحون |
ParagraphDiff | النوع، والنص، وفهرس الصفحة، وسطر البداية/النهاية، والمناطق | مناطق متتالية من النوع نفسه على صفحة واحدة؛ lineCount() | — | — | للقراءة فقط |
ImageDiff | النوع، وفهرس الصفحة، وتجزئة المصدر، وتجزئة الهدف، ومُعرّف الكائن | مُدخل تغيير صورة واحد | — | — | التجزئات سلاسل فارغة في الجهة الغائبة |
MetadataChange | string $field, ?string $sourceValue, ?string $targetValue | تغيير حقل واحد؛ isAdded() وisRemoved() وisModified() | — | — | null يعني أن الحقل غائب |
TextBlock | النص، وx، وy، واسم الخط، وحجم الخط، وفهرس السطر | شريحة نص مُستخرَجة واحدة بموضع تقريبي | — | — | للقراءة فقط |
DiffType | تعداد: Added, Removed, Modified, Unchanged | تصنيف تغيير مدعوم بسلسلة للنص | — | — | راجع ملاحظة Modified في عقد السلوك |
ImageDiffType | تعداد: Added, Removed, Modified, Unchanged | تصنيف تغيير مدعوم بسلسلة للصور | — | — | — |
توقيعات نقاط الدخول
قسم بعنوان «توقيعات نقاط الدخول»public static function compare(string $sourcePdf, string $targetPdf): DiffResult
public static function compareTexts(array $sourcePages, array $targetPages): DiffResult
public static function extractText(string $contentStream): stringpublic function __construct( ?ImageDiffer $imageDiffer = null, ?MetadataDiffer $metadataDiffer = null,)
public function compare(string $sourcePdf, string $targetPdf): StructuredDiffResultpublic function toJson(StructuredDiffResult $result): string
public function toHtml(StructuredDiffResult $result): string
public function toArray(StructuredDiffResult $result): arraypublic static function diff( array $sourceLines, array $targetLines, int $pageIndex = 0, int $maxLines = self::MAX_DIFF_LINES,): arrayعقد السلوك
قسم بعنوان «عقد السلوك»محاذاة الصفحات ومقارنة الأسطر
قسم بعنوان «محاذاة الصفحات ومقارنة الأسطر»يستخرج PdfDiffer::compare() نص كل صفحة، ثم يقارن الصفحة i من المصدر بالصفحة i من الهدف. عندما تختلف أعداد الصفحات، تُعامَل الجهة الناقصة كنص فارغ للصفحات الزائدة. داخل كل زوج صفحات، يُقسَّم النص عند أسطر جديدة وتُشغَّل مقارنة أسطر Myers لكل صفحة. يُصدر المحرك مناطق Added وRemoved وUnchanged. يظهر السطر المُتغيّر كمنطقة Removed إضافةً إلى منطقة Added؛ ولا يُصدر المحرك المُشحون أبدًا مناطق نص Modified. تخدم حالة Modified ودلو DiffResult::$modified النتائج التي يبنيها المُستدعي، لأن مُنشئ DiffResult عام. يَعُدّ totalChanges() المناطق المُضافة والمحذوفة والمعدّلة؛ وتُستبعَد المناطق غير المتغيرة.
مسارات الاستخراج
قسم بعنوان «مسارات الاستخراج»للاستخراج مساران:
- قارئ Artisan الاختياري موجود. عندما يكون صنف
NextPDF\Parser\PdfReaderالاختياري مُثبَّتًا، تُقرأ مجاري محتوى الصفحات من خلاله للحصول على نص دقيق على مستوى الصفحة. يقود عددُ صفحات المُذيّل (trailer) الحلقةَ. الصفحة التي تُخفق قراءتها تُسهم بنص فارغ بدلًا من إجهاض المقارنة. - المسار الاحتياطي. يحدّد ماسحٌ مُقيَّد على مستوى البايت أزواج
stream/endstreamعبرstrpos، ويفكّ ضغط بيانات FlateDecode بسقف إخراج صارم قدره 50 MB، ويعكس مرشّح مُتنبّئ PNG عندما يطلب قاموس المجرى ذلك عبر/DecodeParmsوفق ISO 32000-2:2020 §7.4.4.4. المُتنبّئ المُشوَّه أو غير المدعوم يترك البايتات المفكوكة دون تغيير. يُلحِق المسار الاحتياطي كل النص المُستعاد في دلو صفحة واحد، لذا فإن المحاذاة على مستوى الصفحة تكون دقيقة على مستوى الصفحة فقط في مسار القارئ.
يحلّل كلا المسارين مُعامِلات إظهار النص من §9.4 وهي Tj وTJ و'. تتعقّب آلة الحالة BT/ET وTm (المنشأ فقط) وTd/TD وT* وTf.
المقارنة المُهيكلة
قسم بعنوان «المقارنة المُهيكلة»يُجري StructuredDiffer::compare() مقارنة النص، ويجمّع المناطق المتتالية من النوع نفسه على الصفحة نفسها في فقرات (بما في ذلك التسلسلات غير المتغيرة)، ثم يُجري مقارنة الصور والبيانات الوصفية ويُجمِّع DiffSummary. تغطي أعداد فقرات الملخّص الفقرات المُضافة والمحذوفة والمعدّلة فقط.
تعدّ مقارنةُ الصور كائنات PDF بنيويًا. يُحكَم امتداد جسم المجرى بإدخال /Length الخاص به وفق §7.3.8.2، لذا فإن البايتات الثنائية التي تشبه بنية الكائنات مجرد تشابه لا تُسجَّل أبدًا ككائنات وهمية. تُفكّ مجاري الكائنات المضغوطة (/Type /ObjStm) وفق §7.5.7 كي تكون كائنات الصور XObjects المتداخلة داخلها ظاهرة. تُجزَّأ كل صورة مُكتشَفة بمحتواها باستخدام دالة xxh128 غير التشفيرية؛ والهوية هي زوج دلو الصفحة ورقم الكائن. تُنسَب الصور التي لا صفحة مالكة لها في ترتيب المجرى إلى الصفحة 0.
تحلّ مقارنةُ البيانات الوصفية قاموس /Info الحقيقي عبر المُذيّل عند الإمكان، بحيث لا يُخلَط بين رمز حقل خادع داخل مجرى محتوى وبين البيانات الوصفية للمستند. تُفكّ قيم الحقول كسلاسل PDF: الصيغة الحرفية وفق §7.3.4.2 والصيغة الست عشرية وفق §7.3.4.3. بدون مُذيّل قابل للحل، يرجع البحث إلى المُدخل بأكمله. تُقارَن التواريخ كسلاسل مفكوكة الترميز، لا كطوابع زمنية مُحلّلة.
مخرجات التقرير
قسم بعنوان «مخرجات التقرير»يُعيد DiffFormatter::toJson() نصَّ JSON منسّقًا للطباعة ويُرمِّز باستخدام JSON_THROW_ON_ERROR، بحيث يرفع إخفاقُ الترميز JsonException بدلًا من إعادة false. يُعيد toHtml() جزءًا من نوع <div class="nextpdf-diff">؛ ويمرّ نص الفقرات وقيم البيانات الوصفية عبر تهريب كيانات HTML. لا يوجد إخراج PDF مرئي لمقارنة جنبًا إلى جنب بخط أحمر. بالنسبة إلى المُدخلات المتطابقة، تكون المناطق والمخرجات المنسّقة حتمية.
الحالات الحدّية وأنماط الإخفاق
قسم بعنوان «الحالات الحدّية وأنماط الإخفاق»- محاذاة الصفحات موضعية. صفحة واحدة مُدرَجة أو محذوفة تُزيح المحاذاة لجميع الصفحات اللاحقة وتُضخّم أعداد التغييرات اللاحقة.
- في مسار الاستخراج الاحتياطي، يقع كل النص على فهرس الصفحة 0. مقارنة مستند مُستخرَج بالقارئ مع توقعات من المسار الاحتياطي تُنتج نسبة صفحات مختلفة.
- المخزن المؤقت للمصدر أو الهدف الذي لا يبدأ بـ
%PDFيُخفق بـInvalidArgumentExceptionقبل أي مقارنة. - أكثر من 10,000 سطر مجمّع في زوج صفحات واحد يُخفق بـ
OverflowException(حد عدد الأسطر). - نصّا صفحتين يتشاركان أسطرًا قليلة جدًا يُخفقان بـ
OverflowExceptionبمجرد أن تتجاوز مسافة تحرير Myers الحد المقيَّد بالذاكرة. المراجعات المشروعة تتشارك معظم الأسطر وتبقى غير متأثرة؛ أما المُدخلات العدائية منخفضة التشارك فتُطلق الحد. - إخراج المجرى الاحتياطي بعد فك الضغط الأكبر من 50 MB يُخفق بـ
OverflowException(حد قنبلة فك الضغط). يستخدم الماسحstrpos، لا تعبيرًا نمطيًا غير مُقيَّد، لذا لا يمكن لمُدخل مُصمَّم أن يُطلق تراجعًا كارثيًا. - مُعامِل إظهار النص
"يُرمَّز إلى وحدة لكنه لا يُنتج أي كتلة نص في 3.1.0؛ والنص المُظهَر عبر"وحده لا يشارك في المقارنة. - ملفات PDF الممسوحة ضوئيًا والمكوّنة من صور فقط تُنتج مقارنة نص قليلة أو معدومة. لا يعمل أي OCR.
- كشف تغيير الصور بنيوي، لا إدراكي. فهو لا يُنقّط الصفحات، والصورة المُعاد ترميزها ببكسلات متطابقة تُبلَّغ كمعدّلة عندما تختلف بايتاتها.
- الصورة التي يتغيّر دلو صفحتها أو رقم كائنها بين المراجعات تُبلَّغ كزوج محذوف-مضاف، لا كمعدّلة.
- مجاري الكائنات المضغوطة بمرشّحات غير FlateDecode تُتجاوز على نحوٍ مُغلَق عند الإخفاق؛ ولا تُقارَن صورها الأعضاء.
- لا تحدث أي عملية تشفيرية في هذه الوحدة، لذا لا يوجد سلوك خاص بوضع FIPS. تجزئة الصورة لكشف التغيير فقط ولا تحمل أي وزن نزاهة أو إثبات.
المطابقة
قسم بعنوان «المطابقة»| الادّعاء | المعيار | البند |
|---|---|---|
يُحلَّل مُعامِلا إظهار النص Tj وTJ لأغراض الاستخراج | ISO 32000-2:2020 | §9.4 |
تبدأ بيانات المجرى الاحتياطي بعد CRLF أو LF الذي يلي الكلمة المفتاحية stream | ISO 32000-2:2020 | §7.3.8.1 |
امتدادات مجرى مسح الصور يُحكَم بها بإدخال القاموس /Length | ISO 32000-2:2020 | §7.3.8.2 |
تُحدَّد أعضاء مجرى الكائنات عبر جدول أزواج /N وإزاحة /First | ISO 32000-2:2020 | §7.5.7 |
يتبع عكسُ مُتنبّئ PNG معامِل Predictor في /DecodeParms | ISO 32000-2:2020 | §7.4.4.4 |
| تفكّ قيمُ البيانات الوصفية صيغتَي السلسلة الحرفية والست عشرية | ISO 32000-2:2020 | §7.3.4.2, §7.3.4.3 |
| إخراج PDF مرئي لمقارنة جنبًا إلى جنب بخط أحمر | — | غير مدعوم (JSON/HTML فقط) |
جميع البنود مُعاد صياغتها؛ ولا تُعيد NextPDF إنتاج النص المعياري. هذه بيانات قدرة، لا شهادات؛ ولا تحمل NextPDF أي شهادة ولا تمنح أيًّا منها. يُعيد استرجاعُ النص بناءَ نص الأسطر من مُعامِلات إظهار النص. وهو لا يُشغّل آلة حالة النص الكاملة في §9.4، لذا فإن المقارنة على مستوى المحتوى، لا على مستوى الهندسة.
ملاحظات التطوير
قسم بعنوان «ملاحظات التطوير»- التوفّر ضمن حزمة Pro:
PdfDifferوDiffEngineوTextExtractorوكائنات القيمة الخاصة بها منذ 1.8.0؛ وStructuredDifferوDiffFormatterوImageDifferوMetadataDifferوكائناتها منذ 2.2.0. جميعها حالية فيnextpdf/pro3.1.0. - فضّل
PdfDiffer::compareTexts()عندما يكون نص الصفحة متوفّرًا بالفعل؛ فهو يتخطى الاستخراج وأنماط إخفاقه بالكامل. - يُحسّن قارئ Artisan الاختياري دقة الاستخراج ونسبة الصفحات. يُكتشَف في زمن التشغيل ولا يُشترَط أبدًا.
- التقط
OverflowExceptionعند مقارنة مُدخل غير موثوق؛ فالحدود رفض متعمَّد مُغلَق عند الإخفاق، لا أخطاء عابرة. - يُصدر
DiffFormatter::toHtml()أسماء أصناف (diff-addedوdiff-removedوdiff-modifiedوdiff-unchanged) لكن دون أي ورقة أنماط؛ وفّر CSS الخاص بك. - أنشئ
StructuredDifferبمقارِنات بديلة (stub) في الاختبارات لعزل مسار النص عن مسح الصور والبيانات الوصفية.
حدود النشر
قسم بعنوان «حدود النشر»توثّق هذه الصفحة السلوك القابل للملاحظة خارجيًا وسطح واجهة برمجة التطبيقات العامة المدعوم فقط. مسارات أسماء النطاقات الداخلية، وأصناف المساعدة، وجداول الآليات، وأسماء ملفات كتيّب التشغيل، وبادئات التذاكر خارج النطاق.
اطّلع أيضًا
قسم بعنوان «اطّلع أيضًا»- Diff (القدرة) — التثبيت، والبدء السريع، وعيّنات الإنتاج.
- Converter — المرجع المتعمّق
- Filter — المرجع المتعمّق