مقدمة: معسكران، معركة واحدة
\n\nكل مطور PHP يجد نفسه عاجلاً أم آجلاً أمام خيار: هل يكتب بأسلوب البرمجة الوظيفية أم يغوص في عالم الكائنات والكلاسات؟ الأمر يشبه الاختيار بين سكين سويسري متعدد الاستخدامات وأداة متعددة الوظائف — كلاهما يحل المشكلات، لكن بطرق مختلفة. في هذا المقال، سنحلل البرمجة الوظيفية مقابل البرمجة الكائنية في PHP، ونلقي نظرة على كود حقيقي، ونقرر متى نستخدم أي أداة.
\n\nPHP لغة فريدة. وُلدت كلغة إجرائية، ثم تطورت لتدعم البرمجة الكائنية، وفي الإصدارات الحديثة (7.4+، 8.x) تدمج ميزات وظيفية بقوة: دوال السهم، الإغلاقات، والتصنيف. هذا يعني أنه يمكنك مزج الأساليب. لكن كيف لا تتوه؟ دعنا نكتشف.
\n\nالأساسيات: كيف يختلف العالمان
\n\nالبرمجة الوظيفية (Functional Programming)
\n\nالفكرة الأساسية هنا هي الدوال. دوال نقية بدون آثار جانبية، تعيد دائمًا نتيجة متوقعة. لا حالة مشتركة، ولا تغيير في المتغيرات. تنتقل البيانات عبر سلسلة كخط إنتاج.
\n\n// أسلوب وظيفي: بسيط، قابل للتوقع\n$numbers = [1, 2, 3, 4, 5];\n\n$result = array_map(\n fn($n) => $n * 2,\n array_filter($numbers, fn($n) => $n % 2 === 0)\n);\n\nprint_r($result); // [4, 8]\n\nهل لاحظت؟ لم نغير المصفوفة الأصلية، ولم نستخدم حلقات. كل شيء تصريحي: خذ الأعداد الزوجية، ضاعفها، أعطِ النتيجة. هذا يوفر وقت التصحيح — لا توجد آثار جانبية.
\n\nالبرمجة الكائنية (OOP)
\n\nالبرمجة الكائنية تبنى حول الكائنات — كيانات تخزن الحالة والسلوك. الكلاسات تغلف البيانات، والوراثة توسع الوظائف، وتعدد الأشكال يسمح بتغيير المنطق بمرونة.
\n\n// أسلوب كائني: هيكل وإعادة استخدام\nclass NumberProcessor {\n private array $numbers;\n\n public function __construct(array $numbers) {\n $this->numbers = $numbers;\n }\n\n public function getEvens(): array {\n return array_filter($this->numbers, fn($n) => $n % 2 === 0);\n }\n\n public function multiplyBy(int $factor): self {\n $this->numbers = array_map(fn($n) => $n * $factor, $this->numbers);\n return $this;\n }\n\n public function getResult(): array {\n return $this->numbers;\n }\n}\n\n$processor = new NumberProcessor([1, 2, 3, 4, 5]);\n$result = $processor->getEvens()->multiplyBy(2)->getResult();\nprint_r($result); // [4, 8]\n\nهنا أنشأنا كائنًا يخزن الحالة. يمكن استدعاء الدوال بشكل متسلسل. الميزة: إذا أردت إضافة عملية جديدة — فقط أضف دالة في الكلاس.
\n\nمتى تتفوق البرمجة الوظيفية
\n\n1. معالجة البيانات بدون آثار جانبية
\n\nتخيل أنك تكتب محلل سجلات أو محول عملات. البيانات تتدفق عبر خط إنتاج: اقرأ → صفّي → حوّل → احفظ. الدوال هنا الخيار المثالي. لا تعتمد على حالة خارجية، وسهلة الاختبار.
\n\n2. المجموعات والمصفوفات
\n\nPHP تقدم دوال قوية للتعامل مع المصفوفات: array_map، array_filter، array_reduce. مع دوال السهم (PHP 7.4+) يصبح الكود كالشعر.
$users = [\n ['name' => 'آمنة', 'age' => 25],\n ['name' => 'بسام', 'age' => 17],\n ['name' => 'فاطمة', 'age' => 30],\n];\n\n$adultNames = array_map(\n fn($user) => $user['name'],\n array_filter($users, fn($user) => $user['age'] >= 18)\n);\n\n// ['آمنة', 'فاطمة']\n\nنقي، قابل للقراءة، بدون كلاسات. للتحويلات البسيطة — هذا هو الخيار الأفضل.
\n\n3. الاختبار بدون Mocks
\n\nالدوال ليس لها حالة، لذا اختبارها سهل. لا حاجة لإنشاء Mocks أو Stubs معقدة. فقط مرر البيانات — واحصل على النتيجة.
\n\nمتى تكون البرمجة الكائنية لا غنى عنها
\n\n1. منطق الأعمال المعقد مع الحالة
\n\n