المصفوفات المتقدمة والفرز
في الدرس السابق، تعرفت على ماهية المصفوفات وكيفية إنشائها والتجول فيها. ويكشف هذا الدرس عن المجال الذي تبرز فيه مصفوفات PHP حقًّا — وهو مجموعة كبيرة من دوال المصفوفات التي تتيح لك كتابة كود موجز بشكل مذهل.
1. دمج المصفوفات
PHP
<?php
$arr1 = ["a" => "apple", "b" => "banana"];
$arr2 = ["b" => "blueberry", "c" => "cherry"];
// array_merge: merge — same-name string keys: latter overwrites former
$merged = array_merge($arr1, $arr2);
// ["a" => "apple", "b" => "blueberry", "c" => "cherry"]
// + operator: merge — same-name keys: former takes priority (keeps left side)
$union = $arr1 + $arr2;
// ["a" => "apple", "b" => "banana", "c" => "cherry"]
// Note: "b" kept "banana" from the left side
// array_merge re-indexes numeric arrays
$nums1 = [1, 2, 3];
$nums2 = [4, 5];
print_r(array_merge($nums1, $nums2)); // [1,2,3,4,5] (re-indexed)
print_r($nums1 + $nums2); // [1,2,3] (+ doesn't re-index)
?>
array_merge |
+ المشغل |
|
|---|---|---|
| نفس مفاتيح السلسلة | الأخير يحل محل الأول | الأول يحل محل الأخير |
| المصفوفات المفهرسة | إعادة الفهرسة | لا يتم إعادة الفهرسة؛ يتم تجاهل الفهارس الموجودة |
💡 نصيحة: لدمج البيانات التي أرسلها المستخدم مع الإعدادات الافتراضية، استخدم
$config = array_merge($defaults, $userInput); — حيث تتجاوز قيم المستخدم القيم الافتراضية.
2. الفرق والتقاطع بين المصفوفات
PHP
<?php
$a = [1, 2, 3, 4, 5];
$b = [4, 5, 6, 7];
// array_diff: values in $a but not in $b
print_r(array_diff($a, $b)); // [1, 2, 3]
// array_intersect: values in both $a and $b
print_r(array_intersect($a, $b)); // [4, 5]
?>
3. عمليات المفتاح والقيمة
PHP
<?php
$user = ["name" => "John", "age" => 25, "city" => "New York"];
// array_keys: get all keys
print_r(array_keys($user));
// ["name", "age", "city"]
// array_values: get all values (reset to indexed array)
print_r(array_values($user));
// ["John", 25, "New York"]
// Check key or value
var_dump(array_key_exists("age", $user)); // bool(true)
var_dump(in_array("Chicago", $user)); // bool(false)
// array_search: find the key for a given value
$key = array_search(25, $user);
echo $key; // "age"
?>
4. array_filter — تصفية المصفوفات
احتفظ بالعناصر بناءً على ما إذا كانت دالة الاستدعاء تعيد القيمة «true» أم «false»:
PHP
<?php
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Keep only even numbers
$even = array_filter($numbers, function($n) {
return $n % 2 == 0;
});
print_r($even); // [1=>2, 3=>4, 5=>6, 7=>8, 9=>10]
// Note: the keys are preserved! Use array_values to reset them:
print_r(array_values($even)); // [2, 4, 6, 8, 10]
// No callback: filters out values that equal false
$mixed = [0, "hello", "", null, false, "world", []];
$filtered = array_filter($mixed);
print_r($filtered); // [1=>"hello", 5=>"world"]
?>
▶ مثال: تصفية بيانات النماذج الفارغة
PHP
<?php
// Clean up a user-submitted form (remove empty fields)
$form = [
"name" => "John",
"email" => "",
"phone" => null,
"city" => "New York",
"comment" => false
];
$cleaned = array_filter($form, function($val) {
return $val !== "" && $val !== null && $val !== false;
});
print_r($cleaned);
// ["name"=>"John", "city"=>"New York"]
?>
5. array_map — تطبيق دالة على كل عنصر
PHP
<?php
$numbers = [1, 2, 3, 4, 5];
// Multiply every number by 2
$doubled = array_map(function($n) {
return $n * 2;
}, $numbers);
print_r($doubled); // [2, 4, 6, 8, 10]
// With an arrow function
$squares = array_map(fn($n) => $n * $n, $numbers);
print_r($squares); // [1, 4, 9, 16, 25]
// Process multiple arrays simultaneously
$a = [1, 2, 3];
$b = [4, 5, 6];
$sums = array_map(fn($x, $y) => $x + $y, $a, $b);
print_r($sums); // [5, 7, 9]
?>
6. مجموعة عمليات الفرز الكاملة
يحتوي لغة PHP على 11 دالة فرز، لكن ما عليك سوى تذكر 4 أزواج + دالة مخصصة واحدة:
PHP
<?php
$fruits = ["orange", "apple", "banana"];
$ages = ["Peter" => 32, "John" => 28, "Jane" => 35];
// === Sort by Value ===
sort($fruits); // Ascending, re-indexes → ["apple","banana","orange"]
rsort($fruits); // Descending, re-indexes → ["orange","banana","apple"]
// === Sort by Value, Preserve Keys ===
asort($ages); // Values ascending, preserve keys → ["John"=>28,"Peter"=>32,"Jane"=>35]
arsort($ages); // Values descending, preserve keys → ["Jane"=>35,"Peter"=>32,"John"=>28]
// === Sort by Key ===
ksort($ages); // Keys ascending → ["Jane"=>35,"John"=>28,"Peter"=>32]
krsort($ages); // Keys descending → ["Peter"=>32,"John"=>28,"Jane"=>35]
// === Custom Sort ===
usort($fruits, fn($a, $b) => strlen($a) <=> strlen($b));
// Sort by string length ascending
?>
| الوظيفة | الترتيب حسب | الاتجاه | هل يتم الاحتفاظ بالمفاتيح؟ |
|---|---|---|---|
sort |
القيمة | ترتيب تصاعدي | ❌ إعادة الفهرسة |
rsort |
القيمة | تنازلي | ❌ |
asort |
القيمة | تصاعدي | ✅ |
arsort |
القيمة | ترتيب تنازلي | ✅ |
ksort |
مفتاح | تصاعدي | ✅ |
krsort |
المفتاح | تنازلي | ✅ |
usort |
مخصص | مخصص | ❌ |
uasort |
مخصص (القيمة) | مخصص | ✅ |
💡 نصيحة:
asort / ksort تحافظان على علاقات المفتاح والقيمة — استخدمهما للمصفوفات الترابطية (مثل كشوف الدرجات). sort / rsort تعيدان الفهرسة — استخدمهما للقوائم العادية.
7. المصفوفات متعددة الأبعاد
المصفوفات داخل المصفوفات — تُستخدم عادةً لتخزين البيانات المنظمة:
PHP
<?php
$students = [
["name" => "Alice", "score" => 92, "city" => "New York"],
["name" => "Bob", "score" => 85, "city" => "Chicago"],
["name" => "Charlie", "score" => 78, "city" => "New York"],
];
// Access: outer first, then inner
echo $students[0]["name"]; // Alice
// Traverse
foreach ($students as $s) {
echo "{$s['name']}: {$s['score']} points<br>";
}
// Extract a single column with array_column
$names = array_column($students, "name");
print_r($names); // ["Alice", "Bob", "Charlie"]
$scores = array_column($students, "score", "name");
// ["Alice"=>92, "Bob"=>85, "Charlie"=>78]
// The third argument specifies which column to use as keys
?>
▶ مثال: فرز المصفوفات متعددة الأبعاد
PHP
<?php
$products = [
["name" => "Keyboard", "price" => 299],
["name" => "Mouse", "price" => 149],
["name" => "Monitor", "price" => 1299],
["name" => "Mousepad", "price" => 29],
];
// Sort by price low to high (custom comparison function)
usort($products, fn($a, $b) => $a["price"] <=> $b["price"]);
foreach ($products as $p) {
echo "{$p['name']}: \${$p['price']}<br>";
}
// Mousepad: $29
// Mouse: $149
// Keyboard: $299
// Monitor: $1299
?>
يُعد مشغل السفينة الفضائية <=> الخيار الأمثل هنا — حيث يقوم سطر واحد بفرز مصفوفة متعددة الأبعاد. إنها أناقة بحتة.
8. تفكيك المصفوفات (PHP 7.1+)
استخدم [] أو list() لتفكيك قيم المصفوفة إلى متغيرات متعددة دفعة واحدة:
PHP
<?php
// Destructure an indexed array
$info = ["John", 25, "New York"];
[$name, $age, $city] = $info;
echo $name; // John
// Destructure an associative array (PHP 7.1+)
$user = ["name" => "Jane", "age" => 22];
["name" => $n, "age" => $a] = $user;
echo $n; // Jane
// Selective extraction (PHP 7.1+)
[2 => $city, 0 => $name] = $info;
echo $city; // New York
?>
❓ أسئلة شائعة
س كيف أختار بين المشغل
array_merge والمشغل +؟ج استخدم
array_merge في معظم الحالات. لدمج إعدادات المستخدم مع الإعدادات الافتراضية: $config = array_merge($defaults, $userConfig); — حيث تتجاوز إعدادات المستخدم الإعدادات الافتراضية. لا تستخدم + إلا عندما تحتاج تحديدًا إلى «الاحتفاظ بالمفاتيح الموجودة وتجاهل التكرارات».س تُعد دالة usort قوية — متى ينبغي عليّ استخدامها فعليًّا؟
ج عندما تحتاج إلى قواعد فرز مخصصة — على سبيل المثال، الفرز حسب السعر، أو الفرز حسب طول الاسم، أو الفرز حسب سمة متداخلة بعمق.
usort + <=> هما ثنائي مثالي.س أصبحت المصفوفة متعددة الأبعاد الخاصة بي عميقة جدًّا — ماذا عليّ أن أفعل؟
ج إذا تجاوزت مستويات التداخل 3 مستويات، ففكر في استخدام الكائنات أو الفئات لتنظيم بياناتك بدلاً من ذلك. تُعد المصفوفات خيارًا رائعًا للهياكل البسيطة؛ أما الكائنات فهي أكثر وضوحًا للهياكل المعقدة.
📖 ملخص
array_mergeيدمج المصفوفات (حيث يتم الكتابة فوق المصفوفة الثانية)؛+يدمج المصفوفات (حيث تُعطى الأولوية للمصفوفة الأولى)array_filterيقوم بالتصفية حسب الشرط؛array_mapيقوم بتحويل كل عنصرarray_keys/array_valuesاستخراج المفاتيح أو القيم؛in_arrayالتحقق من القيمsort/asort/ksortبالإضافة إلى 3 طرز أخرى تغطي معظم احتياجات الفرزusort+<=>للفرز المخصص — أداة قوية لفرز المصفوفات متعددة الأبعادarray_columnيستخرج عمودًا معينًا من المصفوفات متعددة الأبعاد- تفكيك المصفوفات
[$a, $b] = $arrمن أجل التعيين الموجز
📝 تمارين
- إذا كان لدينا مصفوفتان من علامات المستخدمين، فاستخدم
array_mergeلدمجهما، وarray_uniqueلإزالة التكرارات من النتيجة. (تلميح:array_unique()يزيل التكرارات.) - من مصفوفة الدرجات
[85, 92, 78, 95, 60]: استخدمarray_filterللاحتفاظ بالدرجات الناجحة فقط (≥ 60)، ثم استخدمarray_mapلإضافة 5 نقاط إضافية إلى كل منها، وأخيرًا قم بفرز النتائج وعرضها. - أنشئ مصفوفة متعددة الأبعاد تحتوي على 5 كتب على الأقل (العنوان، المؤلف، السعر)، واستخدم
usortلفرزها حسب السعر من الأقل إلى الأعلى، ثم استخدمarray_columnلاستخراج جميع أسماء المؤلفين.



