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

أسس PHP 8.4

Spec: ISO 32000-2, §7.5.2 Evidence: Code-backed قيد PHP: ≥8.4 <9.0

يتطلّب ⁨NextPDF⁩ الإصدار ⁨PHP 8.4.⁩ توضّح هذه الصفحة ميزات لغة 8.4 التي يعتمد عليها المحرّك، ولماذا يُعدّ هذا الإصدار حدًّا أدنى صارمًا لا توصية اختيارية، وكيف يُبقي بناء خفض الإصدار المنفصل خيار التشغيل على بيئة تشغيل أقدم متاحًا دون إضعاف قاعدة الشيفرة التي تطالعها.

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

وإذا كان ذلك الحدّ الأدنى غامضًا، ظهرت تكلفتان. تمتلئ قاعدة الشيفرة بطبقات توافق تُخفي المنطق الحقيقي. كما يكفّ نظام الأنواع عن حمل العبء، وهذه بالضبط الخاصية التي لا يقدر خطّ معالجة المستندات على فقدانها.

  • تُعلن الحزمة الأساسية "php": ">=8.4 <9.0". هذا هو القيد الحقيقي، المُتحقَّق منه في composer.json، لا مجرّد طموح في الوثائق.
  • الإصدار 8.4 هو الحدّ الأدنى لأنّ المحرّك يستخدم ميزات لغة 8.4 (وأحدث إصدارات 8.⁨x⁩) بوصفها ضمانات بنيوية: الرؤية غير المتماثلة، والتعدادات المسنودة ذات السلوك، وثوابت الأصناف المُنمَّطة، والحالة للقراءة فقط، والمعطيات المُسمّاة من الدرجة الأولى في واجهة برمجة التطبيقات العامة.
  • لا يزال التشغيل على ⁨PHP 8.1⁩–8.3 ممكنًا عبر بناء خفض إصدار منفصل (النقل الخلفي). إنّه أدوات بناء، لا اعتمادية وقت تشغيل. وهو لا يغيّر الشيفرة التي تطالعها في المستودع الأساسي.
  • الحدّ الأعلى <9.0 مقصود: يُعامَل أيّ إصدار رئيسي جديد من PHP بوصفه أمرًا يجب التحقّق منه، لا افتراضه.

يُحدِّد الحدُّ الأدنى ما تستطيع الشيفرة فعله. لذلك فالطريقة الأدق لشرحه هي إظهار الميزات داخل الشيفرة بدلًا من سردها تجريديًّا.

الرؤية غير المتماثلة تتيح أن تكون الحالة قابلة للقراءة علنًا، لكنها لا تُكتب إلا من نطاق خاص، دون دالّة جلب مكتوبة يدويًّا لكلّ حقل. يستخدمها سياق العرض مباشرةً:

declare(strict_types=1);
final class RenderingContext
{
// Readable everywhere, writable only inside the class.
public private(set) float $x = 0.0;
public private(set) float $y = 0.0;
public private(set) int $currentPageIndex = -1;
public private(set) string $currentContentStream = '';
}

تُزيل ميزة اللغة الواحدة هذه فئة كاملة من التغيير الخارجي العَرَضي. لا يمكن تحريك المؤشّر من خارج المحرّك. يفرض وقتُ التشغيل هذا الضمان، لا عُرفٌ يتعيّن على المراجعين تذكّره.

التعدادات المسنودة ذات السلوك تستبدل الرايات المنطقية المُبعثرة والثوابت النصّية بقيمة مُنمَّطة واحدة تُجيب أيضًا عن أسئلة تتعلق بها. مميِّز توافق المستند تعدادٌ مسنود تُقرِّر دوالُّه النتائج على مستوى المواصفة:

declare(strict_types=1);
enum ConformanceMode: string
{
case Plain = 'plain';
case PdfUa2 = 'pdfua2';
case PdfA4 = 'pdfa4';
case PdfA4f = 'pdfa4f';
public function isTagged(): bool
{
return match ($this) {
self::Plain => false,
default => true,
};
}
/** @return 2|3|4|null */
public function pdfaPart(): ?int
{
return match ($this) {
self::PdfA4, self::PdfA4f => 4,
default => null,
};
}
}

التعداد هو المصدر الوحيد للحقيقة بشأن “هل هذا المستند موسوم وفق المواصفة؟” و”أيُّ جزء من ⁨ISO⁩ ينطبق؟”. وحين كانت تلك الأسئلة تُعبَّر عنها بقيم منطقية فضفاضة، كان يمكن لمواضع عدّة أن تُجيب عنها على نحوٍ متناقض.

ثوابت الأصناف المُنمَّطة تجعل حتى الثوابت جزءًا من عقد الأنواع. تُعلَن الحدود الصارمة لمحرّك ⁨HTML⁩ بوصفها ثوابت مُنمَّطة:

private const int MAX_NESTING_DEPTH = 100;
private const int MAX_ELEMENT_COUNT = 50_000;

المعطيات المُسمّاة جزء من سطح واجهة برمجة التطبيقات العامة، لا حيلة داخلية. تمرّرها البرامج المثالية في مواضع الاستدعاء التي يُفترض أن ينسخها القارئ:

$doc->cell(0, 15, 'Hello, NextPDF!', newLine: true);

ليست هذه استعمالات تزيينية لصياغة جديدة. فكلّ منها يحوّل عُرفًا كان سيتعيّن على المراجع أن يفرضه يدويًّا إلى خاصية يفرضها وقت التشغيل.

هذه الصفحة Evidence: Code-backed . لكلّ ادّعاء أعلاه ملفّ يقابله في المستودع الأساسي، وليس مجرد قائمة ميزات:

  • قيد الإصدار هو قيمة require.php">=8.4 <9.0" في composer.json الأساسي.
  • مثال الرؤية غير المتماثلة هو أسلوب الإعلان الفعلي في src/Core/RenderingContext.php (حقول public private(set)).
  • مثال التعداد يعكس src/Conformance/ConformanceMode.php، وهو enum … : string مسنود تُوجِّه دوالُّه المبنية على match قرارات التوافق.
  • الثوابت المُنمَّطة هي src/Html/HtmlParser.php (private const int MAX_NESTING_DEPTH، MAX_ELEMENT_COUNT).
  • استدعاء المعطى المُسمّى مأخوذ من برامج examples/ المُشحونة.

وللحدّ الأدنى أيضًا بُعد متعلّق بالمعايير. فمهمّة المحرّك هي إصدار ملفّات تتوافق مع Spec: ISO 32000-2, §7.5.2 . يجب على كاتب PDF 2.0 متوافق أن يُعلن إصدار المستند بوصفه 2.0 في ترويسة الملفّ أو في الفهرس. والوفاء بالتزام بهذه الدقّة أسهل بكثير حين تجعل اللغة التي يقوم عليها الكاتب الحالةَ غير المتطابقة صعبة التكوين من الأساس. فالحدّ الأدنى للإصدار وصرامة التنسيق متوائمان.

أصغر برنامج صحيح يستفيد من الحدّ الأدنى منذ البداية. إنّه يعمل على ⁨PHP 8.4⁩، ويستخدم معطًى مُسمّى، ويُنتج ملفًّا متوافقًا:

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Hello World');
$doc->addPage();
$doc->setFont('helvetica', '', 24);
$doc->cell(0, 15, 'Hello, NextPDF!', newLine: true);
$doc->save(__DIR__ . '/hello.pdf');

لا شيء هنا غريب. المغزى أنّ آليّة التنميط الصارم والتعداد والرؤية غير المتماثلة نفسها، التي تجعل بواطن المحرّك جديرة بالثقة، تعمل أصلًا تحت هذا البرنامج المؤلَّف من خمسة أسطر. ولا تختار الانضمام إليها.

أشيع قراءة خاطئة هي أنّ “يتطلّب ⁨PHP 8.4⁩” تعني “لن يعمل إلّا إذا رقّيت إلى 8.4.” بل تعني أنّ الشيفرة الأساسية تستهدف 8.4. ثمّة بناء خفض إصدار منفصل للفرق المثبَّتة على ⁨PHP 8.1⁩–8.3.

من المهمّ توخّي الدقّة بشأن ماهيّة ذلك البناء. إنّه خطّ خفض إصدار قائم على ⁨Rector⁩ يحوّل شيفرة 8.4 إلى مُخرَجات بصياغة أقدم. إنّه بنية بناء تحتية، لا مكتبة وقت تشغيل تضيفها إلى اعتماديات تطبيقك. وهو لا يُدخل قاعدة شيفرة موازية أضعف تنميطًا. الشيفرة المُراجَعة في هذه الصفحات والشيفرة التي تُشحن هما الشيفرة نفسها. النقل الخلفي تحويل يُطبَّق عليها، لا بديل عنها.

توضّح هذه الصفحة لماذا يُعدّ 8.4 الحدّ الأدنى وما الذي يحفظه النقل الخلفي. وهي لا توثّق كيفية تشغيل خطّ خفض الإصدار، ولا إصداراته الهدف المدعومة، ولا محاذيره التشغيلية. فهذه تخصّ وثائق بناء النقل الخلفي ذاتها. والتخطيط الداخلي لحزم تلك الأدوات خارج نطاق هذه الصفحة. استعمالات الميزات المعروضة توضّح أسلوب المحرّك. وهي ليست جردًا كاملًا لكلّ ميزة من ميزات 8.⁨x⁩ التي تستخدمها قاعدة الشيفرة. تُعرَّف واجهات برمجة التطبيقات الدقيقة بالمرجع، لا بهذا الشرح. قيد الإصدار دقيق اعتبارًا من تاريخ مراجعة هذه الصفحة. القيمة المرجعية المعتمدة دائمًا هي كتلة require في composer.json الأساسي.

لا تؤثّر الإصدارة في الحدّ الأدنى للغة. كلّ إصدارة مبنية من شيفرة ⁨PHP 8.4⁩ نفسها:

PHP 8.4 source floor — edition availability
Edition Availability
Core Core مكتوب ليلائم PHP 8.4.
Pro Pro يُبنى على حدّ شيفرة 8.4 الأدنى نفسه.
Enterprise Enterprise يُبنى على حدّ شيفرة 8.4 الأدنى نفسه.
  • الحدّ الأدنى للإصدار — أدنى إصدار من PHP تستهدفه الشيفرة الأساسية (>=8.4). ودونه، لا يمكن التعبير عن ضمانات الأنواع في المحرّك.
  • الرؤية غير المتماثلة — ميزة في ⁨PHP 8.4⁩ تتيح أن تكون الخاصية قابلة للقراءة علنًا لكن قابلة للكتابة فقط من نطاق أضيق (public private(set)).
  • التعداد المسنود — تعداد في ⁨PHP⁩ لحالاته قيم قياسية ويمكنه حمل سلوك (دوال)، يُستخدم هنا بوصفه مصدرًا واحدًا مُنمَّطًا للحقيقة.
  • النقل الخلفي — بناء خفض الإصدار المنفصل القائم على ⁨Rector⁩ الذي يحوّل شيفرة 8.4 إلى مُخرَجات قابلة للتشغيل على ⁨PHP⁩ الأقدم. أدوات بناء، لا اعتمادية وقت تشغيل.
  • وضع التوافق — مميِّز المحرّك المُنمَّط لتحديد عقد توافق ⁨ISO⁩ الذي يجب أن يستوفيه المستند.