الأنواع الصارمة في كل مكان
Spec: ISO 32000-2, §7.5.5 ISO 32000-2 §7.5.5 Evidence: Code-backed PHPStan: Level 10, no src baseline
لمحة سريعة
قسم بعنوان «لمحة سريعة»يُشغّل NextPDF أداة PHPStan عند Level 10 على مصدر المحرّك من دون أساس ضبط لكتم الانتهاكات. توضّح هذه الصفحة لماذا يُعدّ “غياب أساس الضبط” قراراً تصميمياً لا تفصيلاً في الأدوات، وما الذي تمنحه هذه الصرامة عملياً لخط معالجة مهمته ألّا يسيء التعامل مع البيانات بصمت.
لماذا هذا مهم
قسم بعنوان «لماذا هذا مهم»في معظم التطبيقات، تُعدّ الأنواع الصارمة ممارسةً صحّيةً للشيفرة. أما في محرّك PDF، فهي أقرب إلى ضمان للصواب، لأن الصيغة لا تتسامح مع الخطأ. يُتوقّع من القارئ أن يحدّد موضع المحتوى بقراءة الملف من نهايته، عبر المُذيّل وجدول الإحالات المتقاطعة، لذلك يجب أن تكون إزاحات البايت لدى الكاتب دقيقةً تماماً. تأمّل نوعاً يتّسع بهدوء إلى mixed، أو قيمة int تتحوّل بصمت إلى string، أو قيمة قابلة لأن تكون فارغة تُفكّ إشارتها من دون فحص. قد تُنتج أيٌّ من هذه الحالات ملفاً يُفتح على نحو سليم في عارض، ثم يفشل في التحقّق في عارض آخر بعد أسابيع، من دون أيّ تتبّع مكدّس يشير إلى السبب.
الإخفاقات المكلِفة في هذا المجال هي الصامتة منها. الأنواع الصارمة إلى جانب محلّل صارم هي الطريقة التي يحوّل بها المحرّك صنفاً من إخفاقات زمن التشغيل الصامتة إلى إخفاقات صاخبة في زمن البناء.
باختصار
قسم بعنوان «باختصار»- يُحلَّل مصدر المحرّك عند PHPStan Level 10 — أصرم مستوى — كما هو مُتحقَّق منه في
phpstan.neon.dist. - لا يوجد أساس ضبط لكتم المصدر. يثبّت الإعداد تحليل المصدر عند صفر أخطاء. ويُفشِل أيّ ارتداد عمليةَ البناء بدلاً من امتصاصه داخل ملف تجاهل يتضخّم بمرور الوقت.
- المُدخلات القليلة الموجودة في
ignoreErrorsهي ضيّقة النطاق، ومحدّدة بالمعرّف والمسار، ومبرَّرة كلٌّ على حدة في الإعداد (حدود الاعتماد اللين بين الحزم، ومواضع الاختبار الموجّهة إلى الانعكاس) — لا أساس ضبط مُجمَّع. - يُشغّل ملف تعريف صارم منفصل
level: maxويمنع أيّ مُدخلات تجاهل جديدة، فتُلزَم الشيفرة الجديدة بمعيار أكثر إحكاماً. - الأثر المقصود هو ضغط تصميمي: الشيفرة التي لا يمكن التعبير عنها بأمانة نوعية لا تجتاز الفحص، فيُعاد تصميمها بدلاً من كتمها.
كيف يتعامل NextPDF مع ذلك
قسم بعنوان «كيف يتعامل NextPDF مع ذلك»الفرق بين “نستخدم محلّلاً صارماً” و”نستخدم محلّلاً صارماً من دون أساس ضبط” هو جوهر الموضوع، لذلك يجدر توخّي الدقّة.
يسجّل أساس الضبط كلّ انتهاك قائم ويأمر المحلّل بتجاهل تلك الانتهاكات بالتحديد. إنها طريقة عملية لتبنّي التحليل الساكن في قاعدة شيفرة قديمة، لكنها تأتي بكُلفة. إذ يتحوّل أساس الضبط إلى دفتر صامت لدَين اتّفق نظام الأنواع على ألا ينظر إليه. وقد تتسلّل انتهاكات جديدة من النوع نفسه إلى جانب الانتهاكات القائمة. وهكذا يضعف وعد المحلّل من “هذه الشيفرة نظيفة نوعياً” إلى “هذه الشيفرة ليست أسوأ مما كانت عليه.”
لا يقبل NextPDF هذه المقايضة في مصدر المحرّك. يثبّت الإعداد تحليل المصدر عند صفر أخطاء ويفعّل reportUnmatchedIgnoredErrors، حتى إنّ الكتم المتقادم — الذي لم يعد يطابق شيئاً — يُفشِل عملية البناء. حالات التجاهل الضيّقة المتبقّية محدّدة بمعرّف خطأ بعينه وبملف بعينه. ويحمل كلٌّ منها تفسيراً مضمّناً يوضّح لماذا يكون ذلك الحدّ مقصوداً (على سبيل المثال، تعامل النواة مع واجهة Pro/Enterprise من دون اعتماد عيني عليها عمداً). ويمكن للمراجِع أن يقرأ كلّ واحدة منها ويحكم عليها. ولا توجد قائمة مبهمة يصعب تتبّعها.
المسار الذي يُبقي ذلك أميناً:
- Change proposed New or modified engine code.
- Level 10 analysis Strictest PHPStan level over src/, treatPhpDocTypesAsCertain on.
- Zero-error gate No source baseline; unmatched ignores also fail.
- Strict profile level: max; no new ignore entries permitted.
- Redesign, not suppress If it cannot be expressed honestly, the design changes.
treatPhpDocTypesAsCertain جزء من هذا النهج. تُعامَل تعليقات PHPDoc التوضيحية بوصفها حقيقةً مرجعيةً، فلا تكون @param list<T> أو @return non-empty-string تعليقاً يتجاوزه المحلّل بأدب. إنها وعد مُتحقَّق منه. ويُجبَر التعليق التوضيحي ونوع زمن التشغيل على التطابق.
ماذا تقول الأدلّة
قسم بعنوان «ماذا تقول الأدلّة»هذه الصفحة Evidence: Code-backed . الإعداد هو الدليل:
- يضبط
phpstan.neon.distالقيمةlevel: 10وphpVersion: 80400، ويحلّلsrc، ولا يتضمّن أيّ مفتاحbaseline:— لذلك لا يوجدphpstan-baseline.neonلتحليل المصدر. - يضبط الملف نفسه
treatPhpDocTypesAsCertain: trueوreportUnmatchedIgnoredErrors: true، مع ملاحظة مضمّنة بأنّ تحليل المصدر عند L10 مثبَّت عند صفر أخطاء وأنّ أيّ ارتداد يجب أن يُفشِل التكامل المستمرّ. - تُحدَّد كلّ من حالات
ignoreErrorsالمتبقّية بالـidentifierوكثيراً ما بالـpath، مع تعليقات تشرح مبرّر الاعتماد اللين والهدف الانعكاسي — وهي ليست أساس ضبط مُولَّداً بالجملة. - يرث
phpstan-strict.neon.distذلك الإعداد، ويرفع المستوى إلىmax، ويجمّد قائمة التجاهل بحيث لا يجوز إضافة أيّ مُدخل جديد ضمن الملف الصارم.
من منظور المعايير، المسألة مباشرة. يجب أن يُنتج المحرّك ملفات يستطيع القارئ التنقّل فيها من المُذيّل وجدول الإحالات المتقاطعة وفقاً لـ Spec: ISO 32000-2, §7.5.5 ISO 32000-2 §7.5.5 . إزاحات البايت الدقيقة هي مشكلة أنواع قبل أن تكون مشكلة تسلسل. فالإزاحة عدد صحيح يجب ألا يتحوّل بصمت إلى أيّ شيء آخر أبداً. وخط معالجة يكون نظيفاً نوعياً عند Level 10 يكون قد أزال مسبقاً معظم السبل التي قد تنحرف بها العمليات الحسابية بهدوء.
مثال عملي
قسم بعنوان «مثال عملي»تتضح الأنواع الصارمة أكثر ما تتضح حين تُرمَّز قاعدة من قواعد المجال بوصفها نوعاً بدلاً من فحص في زمن التشغيل. يجيب مُميِّز المطابقة عن أسئلة على مستوى المواصفة بـmatch شاملة، فتكون أيّ حالة غير معالَجة خطأً في الأنواع، لا ملف PDF خاطئاً:
declare(strict_types=1);
enum ConformanceMode: string{ case Plain = 'plain'; case PdfUa2 = 'pdfua2'; case PdfA4 = 'pdfa4';
/** @return 2|3|4|null */ public function pdfaPart(): ?int { return match ($this) { self::PdfA4 => 4, default => null, }; }}إنّ @return 2|3|4|null ليست مجرّد توثيق. في ظلّ
treatPhpDocTypesAsCertain، تُفحَص. يُبلَّغ المُستدعي الذي يفترض أنّ النتيجة دائماً int بذلك في زمن التحليل، قبل كتابة بايت واحد من رقم جزء PDF/A غير مطابق.
مفهوم خاطئ شائع
قسم بعنوان «مفهوم خاطئ شائع»المزلق هو قراءة “غياب أساس الضبط” بمعنى “أنّ الشيفرة صادف أنها خالية من الانتهاكات.” والصحيح هو العكس. إنّ غياب أساس الضبط هو السبب، لا نتيجة محظوظة. ولأنه لا يوجد مكان يُركَن فيه انتهاك، يتعيّن كتابة الشيفرة التي قد تُنتج انتهاكاً على نحو مختلف. إنّ Level 10 من دون أساس ضبط للمصدر قيدٌ يصوغ التصميم، لا بطاقة تقييم تصفه بعد وقوعه.
مفهوم خاطئ ثانٍ: أنّ الحفنة من مُدخلات ignoreErrors هي أساس ضبط باسم آخر. وليست كذلك. أساس الضبط مُولَّد بالجملة ومبهم. أما هذه فمكتوبة كلٌّ على حدة، ومحدّدة بالمعرّف، ومشروحة، ومحميّة بـreportUnmatchedIgnoredErrors بحيث لا يمكن أن تتقادم من دون أن يُلاحَظ ذلك.
الحدود والقيود
قسم بعنوان «الحدود والقيود»تتناول هذه الصفحة تحليل مصدر المحرّك. تُحلَّل حزمة الاختبارات ضمن نطاق وإعداد منفصلين ومتمايزين عمداً؛ و”غياب أساس الضبط” هنا قول عن src/، لا ادّعاء بأنّ كلّ تحليل مساعد في المستودع خالٍ من أساس الضبط. يثبت PHPStan سلامة الأنواع، لا صواب السلوك. وهو لا يحلّ محلّ هرم الاختبار، بل يزيل فقط صنفاً من الإخفاقات كان على الاختبارات، لولا ذلك، أن تتعقّبه. المستوى الدقيق والأعلام ومجموعة التجاهل دقيقة اعتباراً من تاريخ مراجعة هذه الصفحة. المصدر المرجعي دائماً هو phpstan.neon.dist وphpstan-strict.neon.dist في مستودع النواة.
لا يغيّر الإصدار هذا الانضباط. يُبنى كلّ إصدار من مصدر Level 10 نفسه:
| Edition | Availability |
|---|---|
| Core | يُحلَّل مصدر النواة عند Level 10 من دون أساس ضبط للمصدر. |
| Pro | بُني Pro على انضباط مصدر Level 10 نفسه. |
| Enterprise | بُني Enterprise على انضباط مصدر Level 10 نفسه. |
مستندات ذات صلة
قسم بعنوان «مستندات ذات صلة»- أسس PHP 8.4 — مزايا اللغة التي يعتمد عليها نظام الأنواع.
- الأخطاء بوصفها ميزة — ماذا يحدث للإخفاقات التي تُظهرها الأنواع الصارمة.
- نموذج خط المعالجة — البنية التي يحميها هذا الانضباط.
مسرد المصطلحات
قسم بعنوان «مسرد المصطلحات»- PHPStan Level 10 — أصرم مستوى تحليل، إذ يعامل القيم غير المُنوَّعة والمُنوَّعة على نحو فضفاض بوصفها أخطاءً لا تحذيرات.
- أساس الضبط — سجلّ مُولَّد للانتهاكات القائمة يُؤمَر المحلّل بتجاهلها. لا يستخدم NextPDF أيّاً منه لمصدر المحرّك.
treatPhpDocTypesAsCertain— إعداد في PHPStan يعامل تعليقات نوع PHPDoc التوضيحية بوصفها حقائق مُتحقَّقاً منها، لا تعليقات استرشادية.reportUnmatchedIgnoredErrors— إعداد يُفشِل عملية البناء حين يكفّ مُدخل تجاهل عن مطابقة أيّ شيء، فيمنع حالات الكتم المتقادمة.- الضغط التصميمي — أثر قيد يفرض كتابة الشيفرة على نحو معيّن، في مقابل فحص يقتصر على قياسها.