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

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

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

ابدأ الدورة

ترتيب مصفوفة الكائنات في PHP: من المبتدئ إلى المحترف

\n\n

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

\n\n

موضوع ترتيب مصفوفة الكائنات حسب خاصية واحدة في PHP هو أحد أكثر الاستفسارات شيوعًا على Stack Overflow (ملايين المشاهدات!). ولا عجب: العمل مع الكائنات هو أساس PHP الحديث، والقدرة على ترتيب البيانات بمرونة هي مهارة لا غنى عنها. دعنا نشرح كل شيء من البسيط إلى المعقد، مع أمثلة حية وشروحات.

\n\n

لماذا لا يمكنك استخدام sort() ببساطة؟

\n\n

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

\n\n

لهذا السبب تحديدًا توجد دوال usort() و uasort() و uksort(). الحرف "u" في الاسم يعني "user-defined" — دالة مقارنة يحددها المستخدم. نحن نكتب بأنفسنا كيفية مقارنة كائنين.

\n\n

مثال أساسي: ترتيب المستخدمين حسب العمر

\n\n

لنفترض أن لدينا كلاس User ومصفوفة من المستخدمين:

\n\n
class User {\n    public $name;\n    public $age;\n    \n    public function __construct($name, $age) {\n        $this->name = $name;\n        $this->age = $age;\n    }\n}\n\n$users = [\n    new User('أحمد', 25),\n    new User('خالد', 30),\n    new User('ليلى', 22),\n    new User('سامر', 28)\n];
\n\n

نحتاج إلى ترتيبهم تصاعديًا حسب العمر. نستخدم usort:

\n\n
usort($users, function($a, $b) {\n    return $a->age <=> $b->age;\n});\n\n// النتيجة:\n// ليلى (22), أحمد (25), سامر (28), خالد (30)
\n\n

لاحظ عامل المركبة الفضائية (spaceship operator) ( <=> ) — ظهر في PHP 7.0 ويجعل الكود موجزًا بشكل لا يصدق. يُرجع -1 أو 0 أو 1، وهو مثالي لدوال المقارنة.

\n\n

شرح آلية عمل usort

\n\n

تأخذ دالة usort() وسيطين:

\n
    \n
  • المصفوفة (تُمرر كمرجع — ستتغير المصفوفة الأصلية)
  • \n
  • دالة رد (Callback) تقارن بين عنصرين
  • \n
\n\n

يجب أن تُرجع دالة الرد:

\n
    \n
  • رقمًا سالبًا (عادةً -1) — إذا كان العنصر الأول أصغر من الثاني
  • \n
  • 0 — إذا كان العنصران متساويين
  • \n
  • رقمًا موجبًا (عادةً 1) — إذا كان العنصر الأول أكبر من الثاني
  • \n
\n\n

عامل المركبة الفضائية يقوم بذلك تلقائيًا. إليك كيف يبدو نفس الترتيب بدونه:

\n\n
usort($users, function($a, $b) {\n    if ($a->age == $b->age) return 0;\n    return ($a->age < $b->age) ? -1 : 1;\n});
\n\n

الفرق واضح: العامل <=> يختصر 4 أسطر في سطر واحد. استخدمه في كل مكان حيث يكون إصدار PHP 7+ مدعومًا.

\n\n

الترتيب حسب النصوص: مراعاة حالة الأحرف والإعدادات المحلية

\n\n

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

\n\n
usort($users, function($a, $b) {\n    return strcmp($a->name, $b->name);\n});\n\n// أو باستخدام عامل المركبة الفضائية:\nusort($users, function($a, $b) {\n    return $a->name <=> $b->name;\n});
\n\n

لكن هناك تفصيل: عامل المركبة الفضائية يراعي حالة الأحرف. النص "apple" سيكون أصغر من "Banana"، لأن رمز الحرف 'a' (97) أصغر من 'B' (66). للترتيب غير الحساس لحالة الأحرف، استخدم strcasecmp():

\n\n
usort($users, function($a, $b) {\n    return strcasecmp($a->name, $b->name);\n});
\n\n

إذا كنت تتعامل مع نصوص عربية أو متعددة اللغات، فكر في استخدام Collator من مكتبة intl للترتيب الصحيح وفقًا للإعدادات المحلية.

المدونات

توصيات الكتب