مقدمة عن Generics في PHP
\n\nفي عالم التطوير الحديث بلغة PHP، يتم إيلاء اهتمام متزايد للكتابة الصارمة وأمان الكود. أحد أقوى الأدوات التي ظهرت في PHP 8.0 هي Generics (الأنواع العامة). إذا كنت مبتدئًا في PHP وتسمع هذا المصطلح لأول مرة - فلا تقلق. في هذه المقالة، سنشرح بلغة بسيطة ما هي Generics، ولماذا هي ضرورية وكيفية استخدامها عمليًا.
\n\nتخيل موقفًا: تكتب دالة يجب أن تعمل مع أنواع مختلفة من البيانات - أرقام، نصوص، كائنات. بدون Generics، سيكون عليك إما استخدام mixed (مما يقلل الأمان) أو كتابة دوال منفصلة لكل نوع. Generics تحل هذه المشكلة بأناقة وفعالية.
في هذه المقالة، سنناقش:
\n- \n
- ما هي Generics ومزاياها الرئيسية \n
- كيفية تعريف الفئات والدوال العامة \n
- أمثلة واقعية للاستخدام في المشاريع \n
- الأخطاء الشائعة للمبتدئين وكيفية تجنبها \n
ما هي Generics ولماذا هي ضرورية؟
\n\nالمشكلة بدون Generics
\n\nلنفترض أنك تنشئ فئة للتعامل مع مجموعة من العناصر. بدون Generics، سيكون عليك استخدام النوع mixed أو كتابة فئات متخصصة لكل نوع بيانات:
<?php\n// نهج سيء - استخدام mixed\nclass Collection {\n private array $items = [];\n\n public function add(mixed $item): void {\n $this->items[] = $item;\n }\n\n public function get(int $index): mixed {\n return $this->items[$index] ?? null;\n }\n}\n\n// الآن يمكن إضافة نص إلى مجموعة أرقام عن طريق الخطأ\n$numbers = new Collection();\n$numbers->add(42);\n$numbers->add('نص'); // لن يحدث خطأ، لكن المنطق معطل\n?>\n\nهذا الكود يعمل، لكنه غير آمن. لا تعرف أي أنواع البيانات مخزنة في المجموعة، وقد تحصل على خطأ أثناء التنفيذ.
\n\nالحل مع Generics
\n\nGenerics تسمح لك بتحديد أنواع البيانات التي ستعمل بها فئتك أو دالتك أو واجهتك. بناء الجملة يشبه الأقواس الزاوية <T>، حيث T هو placeholder (عنصر نائب) لنوع محدد:
<?php\n// نهج جيد - استخدام Generics\nclass Collection<T> {\n private array $items = [];\n\n public function add(T $item): void {\n $this->items[] = $item;\n }\n\n public function get(int $index): ?T {\n return $this->items[$index] ?? null;\n }\n}\n\n// الآن سيتحقق PHP من الأنواع\n$numbers = new Collection<int>();\n$numbers->add(42);\n// $numbers->add('نص'); // Fatal error: Uncaught TypeError\n?>\n\nالآن يعرف مترجم PHP أن المجموعة $numbers يمكنها احتواء الأعداد الصحيحة فقط. أي محاولة لإضافة نص ستسبب خطأ في مرحلة التطوير.
المزايا الرئيسية لـ Generics
\n\n- \n
- أمان الأنواع (Type Safety) - يتم اكتشاف الأخطاء في مرحلة التجميع، وليس أثناء التنفيذ. \n
- قابلية قراءة الكود - من الواضح فورًا أي الأنواع تعمل معها الدالة أو الفئة. \n
- تقليل التكرار - فئة عامة واحدة تحل محل عشرات الفئات المتخصصة. \n
- دعم محسّن لبيئة التطوير (IDE) - الإكمال التلقائي والتلميحات تعمل بشكل صحيح. \n
كيفية استخدام Generics في PHP: أمثلة عملية
\n\n1. الفئات العامة
\n\nالسيناريو الأكثر شيوعًا هو إنشاء المجموعات، الأكوام، الطوابير وهياكل البيانات الأخرى. لنلقِ نظرة على مثال لكومة (Stack):
\n\n<?php\nclass Stack<T> {\n private array $stack = [];\n\n public function push(T $item): void {\n $this->stack[] = $item;\n }\n\n public function pop(): ?T {\n return array_pop($this->stack);\n }\n\n public function isEmpty(): bool {\n return empty($this->stack);\