We are still cooking the magic in the way!
أساسيات PHP
تقنيات المصفوفات المتقدمة
تقنيات معالجة المصفوفات المتقدمة
الآن بعد أن فهمت عمليات ودوال المصفوفات الأساسية، دعنا نستكشف التقنيات المتقدمة التي ستساعدك على كتابة كود PHP أكثر أناقة وكفاءة. هذه الأنماط تستخدم بشكل شائع في التطبيقات الاحترافية.
ملاحظة: تقنيات المصفوفات المتقدمة تجمع بين عدة عمليات لحل المشكلات المعقدة بأناقة. إنها ضرورية لمعالجة البيانات ومعالجة API والمنطق التجاري.
تفكيك وفك حزم المصفوفات
تعيين القائمة (تفكيك المصفوفات)
<?php
// التفكيك الأساسي
$colors = ["red", "green", "blue"];
list($first, $second, $third) = $colors;
echo $first; // red
echo $second; // green
// الصيغة المختصرة (PHP 7.1+)
[$r, $g, $b] = $colors;
echo "$r, $g, $b";
// تخطي العناصر
[$first, , $third] = $colors;
echo "$first and $third"; // red and blue
// مع المصفوفات الترابطية
$person = ["name" => "John", "age" => 30, "city" => "NYC"];
["name" => $name, "age" => $age] = $person;
echo "$name is $age years old";
// التفكيك المتداخل
$data = ["user" => ["name" => "Alice", "email" => "alice@example.com"]];
["user" => ["name" => $userName, "email" => $userEmail]] = $data;
?>
معامل الانتشار (PHP 7.4+)
<?php
// فك حزم المصفوفات في استدعاءات الدوال
$numbers = [1, 2, 3];
function sum($a, $b, $c) {
return $a + $b + $c;
}
echo sum(...$numbers); // 6
// دمج المصفوفات
$arr1 = [1, 2, 3];
$arr2 = [4, 5, 6];
$combined = [...$arr1, ...$arr2];
print_r($combined); // [1, 2, 3, 4, 5, 6]
// إضافة عناصر أثناء فك الحزم
$extended = [0, ...$arr1, 99, ...$arr2, 100];
print_r($extended); // [0, 1, 2, 3, 99, 4, 5, 6, 100]
// مع المصفوفات الترابطية (PHP 8.1+)
$defaults = ["color" => "blue", "size" => "M"];
$custom = ["size" => "L", "style" => "casual"];
$merged = [...$defaults, ...$custom];
print_r($merged);
?>
نصيحة: معامل الانتشار (...) أنظف وغالباً أكثر كفاءة من array_merge() لدمج المصفوفات.
التصفية والتحويل المتقدمة
ربط عمليات المصفوفات
<?php
$products = [
["name" => "Laptop", "price" => 1200, "category" => "electronics"],
["name" => "Phone", "price" => 800, "category" => "electronics"],
["name" => "Desk", "price" => 350, "category" => "furniture"],
["name" => "Chair", "price" => 200, "category" => "furniture"],
["name" => "Monitor", "price" => 400, "category" => "electronics"]
];
// الربط: تصفية الإلكترونيات، التحويل إلى أسماء، الترتيب
$electronicsNames = array_values(
array_map(
function($product) { return $product["name"]; },
array_filter($products, function($p) {
return $p["category"] === "electronics";
})
)
);
sort($electronicsNames);
print_r($electronicsNames); // ["Laptop", "Monitor", "Phone"]
?>
array_walk و array_walk_recursive
<?php
// array_walk - تطبيق دالة على كل عنصر (يعدل في المكان)
$prices = [100, 200, 300];
array_walk($prices, function(&$price) {
$price = $price * 1.1; // إضافة ضريبة 10%
});
print_r($prices); // [110, 220, 330]
// مع المفتاح والبيانات الإضافية
$products = ["laptop" => 1000, "phone" => 500];
array_walk($products, function(&$price, $name, $discount) {
$price = $price * (1 - $discount);
echo "$name: $$price<br>";
}, 0.1); // خصم 10%
// array_walk_recursive - للمصفوفات المتداخلة
$data = [
"user" => ["name" => "john", "email" => "JOHN@EXAMPLE.COM"],
"settings" => ["theme" => "DARK", "lang" => "EN"]
];
array_walk_recursive($data, function(&$value) {
if (is_string($value)) {
$value = strtolower($value);
}
});
print_r($data);
?>
تحذير:
array_walk() تعدل المصفوفة الأصلية. استخدم &$value للتعديل بالإشارة.
عمليات المصفوفات متعددة الأبعاد
ترتيب المصفوفات متعددة الأبعاد
<?php
$students = [
["name" => "Alice", "grade" => 85, "age" => 20],
["name" => "Bob", "grade" => 92, "age" => 19],
["name" => "Charlie", "grade" => 78, "age" => 21],
["name" => "Diana", "grade" => 92, "age" => 18]
];
// الترتيب حسب الدرجة (تنازلي)
usort($students, function($a, $b) {
return $b["grade"] - $a["grade"];
});
// الترتيب حسب حقول متعددة (الدرجة تنازلي، ثم العمر تصاعدي)
usort($students, function($a, $b) {
if ($a["grade"] === $b["grade"]) {
return $a["age"] - $b["age"];
}
return $b["grade"] - $a["grade"];
});
// استخدام معامل السفينة الفضائية (PHP 7+)
usort($students, function($a, $b) {
return [$b["grade"], $a["age"]] <=> [$a["grade"], $b["age"]];
});
print_r($students);
?>
التجميع والفهرسة
<?php
$orders = [
["id" => 1, "customer" => "John", "total" => 100],
["id" => 2, "customer" => "Jane", "total" => 150],
["id" => 3, "customer" => "John", "total" => 200],
["id" => 4, "customer" => "Bob", "total" => 80]
];
// التجميع حسب العميل
$grouped = [];
foreach ($orders as $order) {
$grouped[$order["customer"]][] = $order;
}
print_r($grouped);
// الفهرسة حسب المعرف للبحث السريع
$indexed = array_column($orders, null, "id");
print_r($indexed);
// [1 => [...], 2 => [...], ...]
// جمع الإجماليات حسب العميل
$totals = [];
foreach ($orders as $order) {
$customer = $order["customer"];
$totals[$customer] = ($totals[$customer] ?? 0) + $order["total"];
}
print_r($totals);
// ["John" => 300, "Jane" => 150, "Bob" => 80]
?>
التكرار وتسطيح المصفوفات
تسطيح المصفوفات المتداخلة
<?php
// دالة تسطيح تكرارية
function flattenArray($array) {
$result = [];
foreach ($array as $item) {
if (is_array($item)) {
$result = array_merge($result, flattenArray($item));
} else {
$result[] = $item;
}
}
return $result;
}
$nested = [1, [2, 3], [4, [5, 6]], 7];
$flat = flattenArray($nested);
print_r($flat); // [1, 2, 3, 4, 5, 6, 7]
// استخدام array_merge والانتشار (عمق محدود)
$flat = array_merge(...$nested); // يعمل لمستوى واحد
// التسطيح مع المفاتيح
function flattenWithKeys($array, $prefix = "") {
$result = [];
foreach ($array as $key => $value) {
$newKey = $prefix ? "{$prefix}.{$key}" : $key;
if (is_array($value)) {
$result = array_merge($result, flattenWithKeys($value, $newKey));
} else {
$result[$newKey] = $value;
}
}
return $result;
}
$data = [
"user" => [
"name" => "John",
"address" => ["city" => "NYC", "zip" => "10001"]
]
];
print_r(flattenWithKeys($data));
// ["user.name" => "John", "user.address.city" => "NYC", ...]
?>
نمط خط الأنابيب للمصفوفات
إنشاء خطوط تحويل بيانات قابلة لإعادة الاستخدام:
<?php
// دالة مساعدة لخط الأنابيب
function pipeline($data, ...$operations) {
return array_reduce($operations, function($carry, $operation) {
return $operation($carry);
}, $data);
}
// تعريف عمليات قابلة لإعادة الاستخدام
$filterAdults = fn($users) => array_filter($users, fn($u) => $u["age"] >= 18);
$extractNames = fn($users) => array_map(fn($u) => $u["name"], $users);
$sortAlpha = fn($names) => (function($arr) { sort($arr); return $arr; })($names);
// استخدام خط الأنابيب
$users = [
["name" => "Alice", "age" => 25],
["name" => "Bob", "age" => 17],
["name" => "Charlie", "age" => 30]
];
$result = pipeline(
$users,
$filterAdults,
$extractNames,
$sortAlpha
);
print_r($result); // ["Alice", "Charlie"]
?>
نصيحة: أنماط خطوط الأنابيب تجعل تحويلات البيانات المعقدة قابلة للقراءة والاختبار. كل خطوة معزولة وقابلة لإعادة الاستخدام.
حفظ المصفوفات والتخزين المؤقت
<?php
// دالة الحفظ
function memoize($func) {
$cache = [];
return function(...$args) use ($func, &$cache) {
$key = serialize($args);
if (!isset($cache[$key])) {
$cache[$key] = $func(...$args);
}
return $cache[$key];
};
}
// عملية مكلفة
function fibonacci($n) {
if ($n <= 1) return $n;
return fibonacci($n - 1) + fibonacci($n - 2);
}
// نسخة محفوظة
$fibMemo = memoize("fibonacci");
echo $fibMemo(10); // سريع في الاستدعاءات المتكررة
echo $fibMemo(10); // يرجع النتيجة المخزنة مؤقتاً
?>
تقسيم المصفوفات
<?php
// تقسيم المصفوفة إلى مجموعتين بناءً على شرط
function partition($array, $callback) {
$passed = [];
$failed = [];
foreach ($array as $key => $value) {
if ($callback($value, $key)) {
$passed[$key] = $value;
} else {
$failed[$key] = $value;
}
}
return [$passed, $failed];
}
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
[$even, $odd] = partition($numbers, fn($n) => $n % 2 === 0);
print_r($even); // [2, 4, 6, 8]
print_r($odd); // [1, 3, 5, 7, 9]
// مثال واقعي: تقسيم الطلبات حسب الحالة
$orders = [
["id" => 1, "paid" => true, "amount" => 100],
["id" => 2, "paid" => false, "amount" => 50],
["id" => 3, "paid" => true, "amount" => 200]
];
[$paid, $unpaid] = partition($orders, fn($o) => $o["paid"]);
?>
الفروق والتصحيحات في المصفوفات
<?php
// فرق المصفوفات التكراري
function arrayDiffRecursive($array1, $array2) {
$diff = [];
foreach ($array1 as $key => $value) {
if (!array_key_exists($key, $array2)) {
$diff[$key] = $value;
} elseif (is_array($value) && is_array($array2[$key])) {
$recursiveDiff = arrayDiffRecursive($value, $array2[$key]);
if (!empty($recursiveDiff)) {
$diff[$key] = $recursiveDiff;
}
} elseif ($value !== $array2[$key]) {
$diff[$key] = $value;
}
}
return $diff;
}
$old = [
"name" => "John",
"settings" => ["theme" => "light", "lang" => "en"]
];
$new = [
"name" => "John",
"settings" => ["theme" => "dark", "lang" => "en"]
];
$changes = arrayDiffRecursive($new, $old);
print_r($changes); // ["settings" => ["theme" => "dark"]]
?>
أنماط التحقق من المصفوفات
<?php
// التحقق من بنية المصفوفة
function validateStructure($data, $rules) {
$errors = [];
foreach ($rules as $key => $rule) {
// التحقق من المطلوب
if ($rule["required"] && !isset($data[$key])) {
$errors[$key][] = "الحقل مطلوب";
continue;
}
if (!isset($data[$key])) continue;
$value = $data[$key];
// التحقق من النوع
if (isset($rule["type"]) && gettype($value) !== $rule["type"]) {
$errors[$key][] = "نوع غير صالح";
}
// التحقق من الحد الأدنى/الأقصى للأرقام
if (isset($rule["min"]) && $value < $rule["min"]) {
$errors[$key][] = "القيمة صغيرة جداً";
}
if (isset($rule["max"]) && $value > $rule["max"]) {
$errors[$key][] = "القيمة كبيرة جداً";
}
// مدقق مخصص
if (isset($rule["validator"]) && !$rule["validator"]($value)) {
$errors[$key][] = "فشل التحقق";
}
}
return $errors;
}
// الاستخدام
$data = ["name" => "John", "age" => 15, "email" => "invalid"];
$rules = [
"name" => ["required" => true, "type" => "string"],
"age" => ["required" => true, "type" => "integer", "min" => 18],
"email" => [
"required" => true,
"validator" => fn($v) => filter_var($v, FILTER_VALIDATE_EMAIL)
]
];
$errors = validateStructure($data, $rules);
print_r($errors);
?>
تقنيات تحسين الأداء
<?php
// استخدام array_key_exists للمصفوفات الكبيرة مع قيم null
$largeArray = array_fill_keys(range(0, 10000), null);
// أسرع
if (array_key_exists(5000, $largeArray)) { }
// أبطأ (يرجع false لقيم null)
if (isset($largeArray[5000])) { }
// استخدام array_column لاستخراج البيانات
$users = /* مصفوفة كبيرة من كائنات المستخدمين */;
// أسرع
$emails = array_column($users, "email");
// أبطأ
$emails = array_map(fn($u) => $u["email"], $users);
// تخصيص المصفوفات مسبقاً عندما يكون الحجم معروفاً
$result = array_fill(0, 1000, null);
for ($i = 0; $i < 1000; $i++) {
$result[$i] = $i * 2;
}
// استخدام المولدات لمجموعات البيانات الكبيرة
function getNumbers($max) {
for ($i = 0; $i < $max; $i++) {
yield $i;
}
}
foreach (getNumbers(1000000) as $number) {
// المعالجة بدون تحميل الكل في الذاكرة
}
?>
تمرين:
- أنشئ خط أنابيب يصفي ويحول ويرتب مصفوفة من المنتجات
- نفذ دالة تجمع مصفوفة من الطلبات حسب الشهر وتحسب الإجماليات الشهرية
- اكتب دالة تكرارية للعثور على جميع المسارات في بنية مصفوفة متداخلة
- أنشئ دالة تتحقق من صحة مدخلات المستخدم وتنظفها باستخدام قواعد المصفوفات
- نفذ آلية تخزين مؤقت للمصفوفات تنتهي صلاحيتها بعد وقت معين
نمط واقعي: تحويل البيانات
<?php
// تحويل استجابة API إلى تنسيق التطبيق
function transformUsers($apiResponse) {
return pipeline(
$apiResponse["data"]["users"] ?? [],
fn($users) => array_filter($users, fn($u) => $u["active"]),
fn($users) => array_map(function($user) {
return [
"id" => $user["user_id"],
"name" => $user["first_name"] . " " . $user["last_name"],
"email" => strtolower($user["email"]),
"roles" => array_map("strtolower", $user["roles"] ?? [])
];
}, $users),
fn($users) => array_column($users, null, "id")
);
}
?>
أفضل الممارسات
- استخدم أنماط خطوط الأنابيب للتحويلات المعقدة
- استفد من معامل الانتشار في PHP 7.4+ للحصول على كود أنظف
- استخدم دوال الأسهم (fn) لعمليات رد النداء المختصرة
- نفذ الحفظ للعمليات المكلفة على المصفوفات
- استخدم المولدات لمجموعات البيانات الكبيرة لتوفير الذاكرة
- تحقق من صحة بنيات المصفوفات قبل المعالجة
- ضع في اعتبارك آثار الأداء للعمليات التكرارية
- استخدم معامل السفينة الفضائية (<=>) للترتيب المعقد
تحذير: العمليات التكرارية يمكن أن تكون مكثفة للذاكرة. ضع دائماً في اعتبارك العمق الأقصى للتداخل وأضف حدوداً للسلامة.
الملخص
في هذا الدرس، أتقنت:
- تفكيك المصفوفات ومعامل الانتشار للحصول على كود أنظف
- تقنيات التصفية والتحويل والربط المتقدمة
- ترتيب وتجميع المصفوفات متعددة الأبعاد
- التكرار وتسطيح واجتياز المصفوفات
- أنماط خطوط الأنابيب لتحويل البيانات
- استراتيجيات الحفظ والتخزين المؤقت
- أنماط التقسيم والتحقق من المصفوفات
- تقنيات تحسين الأداء
ستساعدك هذه التقنيات المتقدمة على كتابة كود PHP أكثر أناقة وكفاءة وقابلية للصيانة. تدرب على دمجها لحل المشكلات الواقعية!