حذف عنصر من مصفوفة PHP حسب القيمة: نظرة تحت الغطاء

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

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

ابدأ الدورة

PHP array delete by value (not key): نظرة تحت الغطاء

\n\n

تخيل أنك تكتب سكربت PHP وتعالج قائمة منتجات، وفجأة تحتاج إلى حذف عنصر بسعر أو اسم معين من المصفوفة. أنت تعرف القيمة تمامًا — مثل "تفاح" — لكنك لا تعرف في أي مفتاح توجد. موقف مألوف؟ إذا كان الأمر كذلك، فأنت لست وحدك: سؤال "PHP array delete by value (not key)" يجمع آلاف المشاهدات على Stack Overflow. وهذا ليس من قبيل الصدفة.

\n\n

في PHP لا توجد دالة مدمجة array_remove_by_value(). لذلك يلجأ المطورون إلى الحيل: البعض يكتب حلقة تكرارية، والبعض يستخدم array_search مع unset، والبعض الآخر يستخدم array_diff أو array_filter. لكن ماذا يحدث داخل هذه الدوال؟ أي طريقة أسرع؟ ولماذا قد يعمل نفس الكود بشكل مختلف في إصدارات PHP المختلفة؟

\n\n

في هذه المقالة، لن نقدم لك حلًا جاهزًا فقط — بل سنلقي نظرة تحت الغطاء لكل طريقة، ونحلل أداءها والمزالق المحتملة. وسنعرض أيضًا حالة عملية من حياة مطور باك إند. هيا بنا!

\n\n

الطريقة التقليدية: array_search + unset

\n\n

الإجابة الأكثر شيوعًا على Stack Overflow تبدو كالتالي:

\n\n
<?php\n$array = ['تفاح', 'كمثرى', 'برتقال', 'كمثرى'];\n$value = 'كمثرى';\n\nif (($key = array_search($value, $array)) !== false) {\n    unset($array[$key]);\n}\n?>
\n\n

هذا الكود يجد أول ظهور للقيمة ويحذفه. لكن دعنا نفهم ما يحدث بالضبط.

\n\n

كيف تعمل array_search

\n\n

array_search() هي عملية بحث خطي. تمر PHP عبر المصفوفة من البداية إلى النهاية، وتقارن كل قيمة بالقيمة المطلوبة. المقارنة الافتراضية هي غير صارمة (==)، أي أن 1 و '1' يعتبران متساويين. إذا كنت بحاجة إلى مقارنة صارمة (===)، قم بتمرير المعامل الثالث true:

\n\n
<?php\n$array = [0, '0', 1];\n$key = array_search('0', $array, true); // سيعيد 1 (السلسلة '0')، وليس 0\n?>
\n\n

إذا لم يتم العثور على القيمة، ترجع الدالة false. لذلك التحقق !== false إلزامي — وإلا فإن unset($array[0]) سيحذف العنصر الأول إذا كانت القيمة موجودة في المفتاح 0.

\n\n

المأزق: unset لا يعيد ترتيب المفاتيح

\n\n

بعد unset، تبقى المصفوفة ترابطية — المفاتيح الرقمية لا تتغير. إذا كنت بحاجة إلى مصفوفة كثيفة بمفاتيح متسلسلة، استخدم array_values():

\n\n
<?php\n$array = ['تفاح', 'كمثرى', 'برتقال'];\nunset($array[1]);\n$array = array_values($array); // ['تفاح', 'برتقال'] بمفاتيح 0 و 1\n?>
\n\n

لكن تذكر: array_values() تنشئ مصفوفة جديدة، مما يزيد من استهلاك الذاكرة.

\n\n

حذف جميع التكرارات: array_diff

\n\n

إذا كنت بحاجة إلى حذف جميع العناصر ذات القيمة المحددة، فإن استخدام array_search في حلقة تكرارية ليس فكرة جيدة. الطريقة الأكثر أناقة هي استخدام array_diff():

\n\n
<?php\n$array = ['تفاح', 'كمثرى', 'برتقال', 'كمثرى'];\n$array = array_diff($array, ['كمثرى']);\n// النتيجة: ['تفاح', 'برتقال'] (المفاتيح محفوظة)\n?>
\n\n

ترجع الدالة مصفوفة جديدة تم حذف جميع العناصر المطابقة للقيم في المصفوفة الثانية منها. داخليًا، تستخدم PHP جدول تجزئة للمصفوفة الثانية، لذلك تتم العملية بتعقيد زمني O(n + m)، حيث n هو حجم المصفوفة الأولى و m هو حجم الثانية.

\n\n

مهم: array_diff تقارن القيم كسلاسل نصية ((string) $elem1 === (string) $elem2). بالنسبة للأنواع المختلطة، قد يعطي هذا نتيجة غير متوقعة:

\n\n
<?php\n$array = [0, '0', false];\n$result = array_diff($array, [0]);\n// النتيجة:                

المدونات

توصيات الكتب