مراجعة كود PHP: كيف تتجنب أخطاء المبرمجين المحترفين؟

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

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

ابدأ الدورة

مقدمة: لماذا يطلب منك إعادة كتابة الكود؟

\n\n

لقد كتبت الكود. إنه يعمل. أنت فخور بنفسك. ولكن بعد مراجعة الكود (code review)، يترك المطور الخبير 15 تعليقاً، نصفها يبدأ بـ "ماذا لو..." أو "لنعيد كتابة هذا باستخدام...". هل هذا مألوف لك؟

\n\n

مراجعة كود PHP ليست انتقاداً شخصياً. إنها تتعلق ببقاء المشروع على قيد الحياة. المطورون الخبراء لا ينظرون فقط إلى "يعمل/لا يعمل"، بل ينظرون إلى كيفية تصرف الكود تحت الضغط، وكيف سيدعمه مطور آخر، وكم من الوقت ستستغرقه للعثور على خطأ بعد ستة أشهر.

\n\n

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

\n\n

1. "الأرقام السحرية" والنصوص: الكود يجب أن يتحدث عن نفسه

\n\n

أول ما سيلاحظه الخبير هو الأرقام والنصوص غير الواضحة المنتشرة في الكود. الأرقام السحرية (Magic Numbers) هي نمط مضاد يقتل قابلية القراءة.

\n\n

مثال سيء

\n
if ($user->getAge() > 18) {\n    $discount = $price * 0.1;\n}
\n\n

ماذا سيقول الخبير؟

\n
    \n
  • لماذا بالضبط 18؟ هل هو سن الرشد أم حد الخصم؟
  • \n
  • لماذا 0.1؟ هل هي 10%؟ وماذا لو تغير الخصم؟
  • \n
\n\n

مثال جيد

\n
const ADULT_AGE = 18;\nconst DISCOUNT_RATE = 0.1; // 10%\n\nif ($user->getAge() > ADULT_AGE) {\n    $discount = $price * DISCOUNT_RATE;\n}
\n\n

الآن الكود يروي قصته بنفسه. سيوافق الخبير: يمكن إعادة استخدام الثوابت، وتغييرها في مكان واحد، ولا تحتاج إلى تعليقات.

\n\n

2. غياب الأنواع: PHP 8 ليس عذراً للكتابة الديناميكية

\n\n

PHP لغة ذات كتابة ضعيفة، لكن هذا لا يعني أن تكتب كما في عام 2005. الكتابة الصارمة (Strict Typing) تنقذك من الأخطاء التي يصعب اكتشافها.

\n\n

مثال سيء

\n
function calculateTotal($items, $tax) {\n    $total = 0;\n    foreach ($items as $item) {\n        $total += $item['price'] * $item['quantity'];\n    }\n    return $total * (1 + $tax);\n}
\n\n

ملاحظات الخبير

\n
    \n
  • ما هو $items؟ مصفوفة؟ كائن؟ مجموعة؟
  • \n
  • ما هي بنية العنصر؟ لماذا لا يوجد DTO؟
  • \n
  • ماذا لو تم تمرير $tax كنص "0.2"؟ هل سيحدث دمج نصوص؟
  • \n
\n\n

مثال جيد

\n
declare(strict_types=1);\n\nclass OrderItem {\n    public function __construct(\n        public readonly float $price,\n        public readonly int $quantity\n    ) {}\n}\n\nfunction calculateTotal(array $items, float $taxRate): float {\n    $total = 0.0;\n    foreach ($items as $item) {\n        if (!$item instanceof OrderItem) {\n            throw new InvalidArgumentException('Expected OrderItem');\n        }\n        $total += $item->price * $item->quantity;\n    }\n    return $total * (1 + $taxRate);\n}
\n\n

سيقول الخبير: "أحسنت، تستخدم DTO، خصائص readonly والكتابة الصارمة. الكود قابل للتوقع". هذه هي أفضل ممارسات PHP 8+.

\n\n

3. التداخل العميق والخروج المبكر (Early Return)

\n\n

عندما ترى 5 مستويات من if...else داخل دالة واحدة، يمسك الخبير برأسه. هذا الكود مستحيل القراءة والاختبار وتصحيح الأخطاء.

\n\n

مثال سيء

\n
public function processOrder($order) {\n    if ($order->isPaid()) {\n        if ($order->hasStock()) {\n            if ($order->isShippable()) {\n                // 50 سطراً من المنطق\n                return $this->ship($order);\n            } else {\n                throw new \\Exception('Order cannot be shipped');\n            }\n        } else {\n            throw new \\Exception('Out of stock');\n        }\n    } else {\n        throw new \\Exception('Order not paid');\n    }

المدونات

توصيات الكتب