Generics في PHP: لماذا هي ضرورية وكيفية استخدامها عمليًا

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: ما هي Generics ولماذا هي مهمة في PHP



يتطلب التطوير الحديث في PHP بشكل متزايد كتابة أنواع صارمة وكود قابل لإعادة الاستخدام. أحد الأدوات الرئيسية التي تسمح بتحقيق هذه الأهداف هي Generics (التعميمات). في PHP، تمت إضافة دعم Generics رسميًا بدءًا من الإصدار PHP 8.0، على الرغم من وجود أدوات وتعليقات توضيحية مختلفة سابقًا (على سبيل المثال، عبر PHPDoc).



في هذه المقالة، سنشرح لماذا نحتاج إلى Generics في PHP، وكيف تعمل عمليًا، وسنقدم أمثلة محددة من الكود ستساعدك على كتابة كود أكثر أمانًا وقابلية للقراءة وقابلية للتوسع.



لماذا نحتاج إلى Generics في PHP؟



الهدف الرئيسي لـ Generics هو ضمان أمان الأنواع أثناء التنفيذ، دون فقدان مرونة الكود العام. تخيل أنك تكتب دالة للعمل مع مجموعة من العناصر. بدون Generics، إما أن تستخدم أنواعًا مختلطة (mixed)، أو تكتب دوال منفصلة لكل نوع بيانات. كلا النهجين يؤديان إلى أخطاء وتكرار في الكود.



فيما يلي المزايا الرئيسية لاستخدام Generics:



  • أمان الأنواع — يتم اكتشاف أخطاء الأنواع في مرحلة التجميع، وليس في وقت التشغيل.
  • إعادة استخدام الكود — دالة أو فئة واحدة تعمل مع أي نوع من البيانات.
  • قابلية القراءة — يصبح الكود موثقًا ذاتيًا: يمكنك رؤية الأنواع التي يتم قبولها وإرجاعها على الفور.
  • التكامل مع بيئة التطوير المتكاملة (IDE) — المحررات الحديثة (PhpStorm، VS Code) تفهم الكود مع Generics بشكل أفضل، وتقدم الإكمال التلقائي والتلميحات.


كيف تعمل Generics في PHP: الصيغة والتراكيب الأساسية



في PHP، يتم تنفيذ Generics من خلال قوالب الأنواع، التي تُحدد بين قوسين زاويتين <T>. الحرف T هو تسمية شرطية للنوع الذي سيتم استبداله عند استدعاء الدالة أو إنشاء الكائن. يمكنك استخدام أي أسماء: T، K، V أو أسماء ذات معنى.



1. الدوال العامة



لننظر إلى أبسط مثال — دالة تُرجع العنصر الأول من مصفوفة:



<?php

function firstElement(array $items): mixed { return $items[0] ?? null;}

// الاستخدام$numbers = [1, 2, 3];$first = firstElement($numbers); // النوع mixed، IDE لا يعرف أنه int


مع Generics، يمكننا تحديد أن الدالة تعمل مع مصفوفة من عناصر أي نوع، ولكنها تُرجع بالضبط النوع الذي تم تمريره:



<?php

/** * @template T * @param array<T> $items * @return T|null */function firstElement(array $items): mixed { return $items[0] ?? null;}

// الآن IDE يفهم أن $first هو int|null$first = firstElement([1, 2, 3]);


لاحظ: في PHP 8.0+، يتم دعم Generics من خلال تعليقات PHPDoc. الدعم الأصلي (بدون تعليقات) غير موجود حاليًا، لكن هذا هو المعيار الفعلي للمشاريع الحديثة.



2. الفئات العامة



السيناريو الأكثر شيوعًا لاستخدام Generics هو فئات المجموعات. لننشئ فئة بسيطة Collection يمكنها تخزين عناصر من أي نوع:



<?php

/** * @template T */class Collection { /** @var array<T> */ private array $items = [];

/** * @param T $item * @return void */ public function add(mixed $item): void { $this->items[] = $item; }

/** * @return T|null */ public function get(int $index): mixed { return $this->items[$index] ?? null; }

/** * @return array<T> */ public function all(): array { return $this->items; }}

// الاستخدام$intCollection = new Collection<int>();$intCollection->add(10);$intCollection->add(

المدونات

توصيات الكتب