فرز مصفوفة الكائنات في PHP: حسب خاصية واحدة للمبتدئين

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

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

ابدأ الدورة

فرز مصفوفة الكائنات في PHP: من الفوضى إلى النظام في 5 دقائق

\n\n

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

\n\n

هذا السؤال هو من أكثر الأسئلة شيوعًا على Stack Overflow. آلاف المطورين، من المبتدئين إلى المحترفين، يواجهون مهمة «sort array of objects by one property». واليوم سنحلها مرة واحدة وإلى الأبد. بدون حشو، مع أمثلة حية وشروحات واضحة.

\n\n

لماذا لا تعمل الدالة العادية sort()؟

\n\n

لنفترض أن لدينا مصفوفة كائنات $students:

\n\n
<?php\nclass Student {\n    public $name;\n    public $age;\n    public $score;\n\n    public function __construct($name, $age, $score) {\n        $this->name = $name;\n        $this->age = $age;\n        $this->score = $score;\n    }\n}\n\n$students = [\n    new Student("آنا", 22, 85),\n    new Student("إيفان", 20, 92),\n    new Student("ماريا", 23, 78),\n    new Student("بيتر", 21, 95)\n];\n?>
\n\n

إذا حاولت استدعاء sort($students)، فسيصدر PHP خطأ أو لن يفعل شيئًا. لماذا؟ لأن sort() تعرف كيفية مقارنة الأرقام والسلاسل النصية، لكنها لا تعرف كيفية مقارنة كائنين. تحتاج إلى توضيح: «قارن حسب الخاصية age» أو «قارن حسب name». لهذا، يوجد في PHP دالة خاصة — usort().

\n\n

تعرف على: usort() — أداتك الرئيسية

\n\n

تأخذ الدالة usort() وسيطين: المصفوفة نفسها ودالة المقارنة. يجب أن تعيد دالة المقارنة هذه:

\n
    \n
  • 0 إذا كان العنصران متساويين؛
  • \n
  • رقمًا سالبًا إذا كان العنصر الأول أصغر من الثاني؛
  • \n
  • رقمًا موجبًا إذا كان العنصر الأول أكبر من الثاني.
  • \n
\n\n

يبدو الأمر معقدًا؟ في الواقع هو بسيط. لنقم بفرز الطلاب حسب العمر (تصاعديًا):

\n\n
<?php\nusort($students, function($a, $b) {\n    return $a->age <=> $b->age;\n});\n\n// النتيجة: إيفان (20)، بيتر (21)، آنا (22)، ماريا (23)\n?>
\n\n

لاحظ العامل <=> (السفينة الفضائية). ظهر في PHP 7 ويجعل الفرز موجزًا للغاية. يقارن قيمتين ويعيد -1 أو 0 أو 1. هذا بالضبط ما تحتاجه usort().

\n\n

الفرز تنازليًا: تغيير الإشارة

\n\n

هل تريد الفرز من الأكبر إلى الأصغر سنًا؟ ببساطة قم بتبديل المعاملين في العامل <=>:

\n\n
<?php\nusort($students, function($a, $b) {\n    return $b->age <=> $a->age;  // الآن b يُقارن مع a\n});\n\n// النتيجة: ماريا (23)، آنا (22)، بيتر (21)، إيفان (20)\n?>
\n\n

أو، وهو نفس الشيء، اضرب النتيجة في -1:

\n\n
<?php\nusort($students, function($a, $b) {\n    return -($a->age <=> $b->age);\n});\n?>
\n\n

الفرز حسب السلاسل النصية (أبجديًا)

\n\n

ماذا لو كانت الخاصية سلسلة نصية؟ على سبيل المثال، الاسم. نفس المبدأ، لكن بدلاً من <=> نستخدم strcmp() أو strcasecmp() (للمقارنة غير الحساسة لحالة الأحرف):

\n\n
<?php\n// أبجديًا (أ-ي)\nusort($students, function($a, $b) {\n    return strcmp($a->name, $b->name);\n});\n\n// النتيجة: آنا، إيفان، ماريا، بيتر\n\n// أبجديًا (ي-أ) — ترتيب عكسي\nusort($students, function($a, $b) {\n    return strcmp($b->name, $a->name);\n});\n?>
\n\n

الفرز حسب خاصية رقمية: بديل لـ <=>

\n\n

العامل <=> مناسب، لكن إذا كنت تعمل مع PHP قديم (قبل 7.0)، فهو غير موجود. في هذه الحالة، نكتب المقارنة يدويًا:

المدونات

توصيات الكتب