كيفية التحقق من المصفوفة الترابطية في PHP: أشهر الأخطاء

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

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

ابدأ الدورة

كيفية التحقق مما إذا كانت المصفوفة ترابطية أم متسلسلة في PHP: تحليل أشهر الأخطاء

\n\n

هل سبق لك أن كتبت foreach وحصلت على نتيجة غير متوقعة؟ أو ربما مررت مصفوفة إلى دالة كانت تنتظر قائمة، لكنها استقبلت مصفوفة ترابطية بمفاتيح نصية؟ إذا كان الأمر كذلك، فأنت لست وحدك. سؤال «How to check if PHP array is associative or sequential?» هو من بين الأسئلة الأكثر شيوعًا على Stack Overflow بآلاف المشاهدات. وهذا ليس من قبيل الصدفة: الخلط بين أنواع المصفوفات هو أحد أكبر الأخطاء التي يقع فيها مطورو PHP.

\n\n

في هذه المقالة، سنشرح الفرق بين المصفوفات الترابطية والمتسلسلة (sequential)، ونعرض الأخطاء الشائعة، ونقدم حلولًا عملية. هيا بنا!

\n\n

ما هي المصفوفة المتسلسلة والترابطية؟

\n\n

في PHP، لا يوجد تقسيم صارم بين «القوائم» و«القواميس» كما في Python أو JavaScript. نوع واحد — array — يمكن أن يكون كليهما. لكن من الناحية العملية، من المهم فهم الفرق:

\n\n
    \n
  • المصفوفة المتسلسلة (sequential) — المفاتيح مرتبة: 0، 1، 2، 3... بدون فجوات. مثال: ['تفاحة', 'كمثرى', 'كرز'].
  • \n
  • المصفوفة الترابطية (associative) — المفاتيح عبارة عن نصوص أو أرقام غير مرتبة. مثال: ['name' => 'أحمد', 'age' => 30].
  • \n
\n\n

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

\n\n

الخطأ الشائع رقم 1: استخدام array_keys() والمقارنة مع range

\n\n

أحد أكثر الأساليب شيوعًا هو أخذ مفاتيح المصفوفة، وإنشاء تسلسل من 0 إلى count($array)-1، ثم المقارنة. يبدو منطقيًا، لكن هناك تفاصيل دقيقة.

\n\n
// مثال على نهج خاطئ\nfunction isSequential($arr) {\n    return array_keys($arr) === range(0, count($arr) - 1);\n}\n\n$test = ['a', 'b', 'c'];\nvar_dump(isSequential($test)); // true — صحيح\n\n$test2 = ['x' => 1, 'y' => 2];\nvar_dump(isSequential($test2)); // false — صحيح\n\n$test3 = [0 => 'a', 2 => 'b'];\nvar_dump(isSequential($test3)); // false — صحيح\n\n$test4 = ['0' => 'a', '1' => 'b'];\nvar_dump(isSequential($test4)); // ??? \n
\n\n

المشكلة هي أن PHP تقوم تلقائيًا بتحويل المفاتيح النصية إلى أعداد صحيحة إذا كانت تبدو كأرقام. ['0' => 'a', '1' => 'b'] هي في الواقع مصفوفة متسلسلة، لكن الدالة قد تعطي نتيجة غير متوقعة بسبب المقارنة الصارمة (===).

\n\n

الخلاصة: هذا الأسلوب يعمل، لكن فقط إذا كنت متأكدًا من أنواع المفاتيح. للإنتاج، من الأفضل استخدام طرق أكثر موثوقية.

\n\n

الخطأ الشائع رقم 2: التحقق من المفتاح الأول فقط

\n\n

بعض المطورين يعتقدون: «إذا كان المفتاح الأول هو 0، فالمصفوفة متسلسلة». هذا اعتقاد خاطئ وخطير.

\n\n
function isSequentialByFirstKey($arr) {\n    if (empty($arr)) return true;\n    return array_key_first($arr) === 0;\n}\n\n$bad = [0 => 'a', 'name' => 'أحمد'];\nvar_dump(isSequentialByFirstKey($bad)); // true — ولكن يجب أن تكون false!\n
\n\n

المفتاح الأول هو 0، لكن المصفوفة ترابطية بوضوح. هذا الفحص سيتجاهل المصفوفات المختلطة التي تظهر غالبًا في المشاريع الحقيقية.

\n\n

الخلاصة: لا تحكم على المصفوفة من خلال العنصر الأول فقط. افحص جميع المفاتيح.

\n\n

الخطأ الشائع رقم 3: تجاهل المصفوفات الفارغة

\n\n

المصفوفة الفارغة [] — هل هي متسلسلة وترابطية في نفس الوقت؟ من وجهة نظر PHP — نعم. لكن بعض الدوال تتعطل.

\n\n
function isAssociative($arr) {\n    return count(array_filter(array_keys($arr), 'is_string')) > 0;\n}\n\nvar_dump(isAssociative([])); // false — المصفوفة الفارغة ليست ترابطية\nvar_dump(isAssociative([1, 2, 3])); // false — صحيح\n
\n\n

يبدو منطقيًا، لكن إذا كنت تتوقع أن الدالة سترجع true للمصفوفة الفارغة (كما لو كانت ترابطية)، فأنت مخطئ. المصفوفة الفارغة هي حالة خاصة.

المدونات

توصيات الكتب