تابع array_walk() در PHP
تابع array_walk() یکی از توابع مفید PHP برای اعمال یک callback روی هر عنصر از یک آرایه است. این تابع بهطور درجا (in-place) مقادیر آرایه را پردازش میکند و به شما امکان میدهد با استفاده از یک callback سفارشی، هر عنصر را تغییر دهید یا پردازشهای جانبی انجام دهید. در این مقاله ساختار، کاربردها، تفاوتها با توابع مشابه و مثالهای عملی را با توضیحات کامل بررسی میکنیم.
امضای تابع و پارامترها
ساختار کلی تابع به شکل زیر است:
bool array_walk ( array &$array , callable $callback [, mixed $userdata = NULL ] )توضیح پارامترها:
- $array: آرایهای که باید روی آن کار انجام شود. این آرایه به صورت مرجع (&) به تابع منتقل میشود، بنابراین تغییرات داخل callback در آرایه اصلی منعکس میشود.
- $callback: تابعی که روی هر عنصر اجرا میشود. امضاء معمول callback به صورت
function (&$value, $key, $userdata)است. مقدار$valueمعمولاً بهصورت مرجع دریافت میشود تا امکان تغییر مقدار وجود داشته باشد. - $userdata (اختیاری): دادهای اضافی که به عنوان پارامتر سوم به callback ارسال میشود.
ویژگیهای کلیدی
- انجام عملیات بهصورت in-place (آرایه اصلی تغییر میکند).
- callback میتواند مقدار هر عنصر را تغییر دهد اگر
$valueرا به صورت مرجع بگیرد. - نمیتوان ساختار آرایه (مثل اضافه/حذف کلیدها) را با اطمینان کامل داخل callback تغییر داد؛ برای اینکار
foreachمناسبتر است. - برای آرایههای تو در تو از
array_walk_recursive()استفاده کنید.
مثالهای عملی
مثال 1: تبدیل مقادیر به حروف بزرگ
$arr = ['a' => 'apple', 'b' => 'banana'];
array_walk($arr, function (&$val, $key) {
$val = strtoupper($val);
});
print_r($arr);
در این مثال هر مقدار آرایه به تابع strtoupper سپرده شده و مقادیر اصلی در آرایه $arr تغییر میکنند. دلیل اینکه تغییر اعمال میشود این است که $val بهصورت مرجع گرفته شده است.
مثال 2: ارسال داده اضافی (userdata)
$prices = ['apple' => 100, 'orange' => 150];
$tax = 1.09;
array_walk($prices, function (&$price, $key, $tax) {
$price = round($price * $tax, 2);
}, $tax);
print_r($prices);
اینجا از پارامتر $userdata استفاده شده تا نرخ مالیات به callback پاس داده شود. مقدار هر قیمت بهروزرسانی شده و آرایه اصلی اصلاح میشود.
نمونهای که اشتباه متداول را نشان میدهد
$arr = ['x' => 1, 'y' => 2];
array_walk($arr, function ($v, $k) {
$v = $v * 2; // این تغییر در آرایه اصلی منعکس نمیشود
});
print_r($arr);
در این کد مقدار $v به صورت مقدار (by value) گرفته شده و تغییر داخل callback روی آرایه اصلی تاثیری ندارد. برای اصلاح باید از مرجع استفاده کنید:
array_walk($arr, function (&$v, $k) {
$v = $v * 2;
});
توضیح: گرفتن مقدار به صورت مرجع (&$v) ضروری است اگر هدف تغییر مقادیر آرایه باشد.
مقایسه با توابع دیگر
| تابع | رفتار | زمان مناسب |
|---|---|---|
| array_walk() | درجا، callback برای هر عنصر، امکان دسترسی به key و userdata | وقتی میخواهید آرایه را تغییر دهید یا پردازشهایی با دسترسی به key انجام دهید |
| array_map() | خروجی آرایه جدید، callback روی مقادیر اجرا میشود | وقتی میخواهید آرایه جدیدی بسازید و دستکاری ساختار را نیاز ندارید |
| foreach | کنترل کامل، میتوان عناصر را اضافه/حذف کرد | وقتی نیاز به تغییر ساختار آرایه یا خوانایی بیشتر دارید |
| array_walk_recursive() | مانند array_walk اما بازگشتی برای آرایههای تو در تو | برای پردازش مقادیر در ساختارهای چندبعدی |
موارد استفاده رایج
- فرمت کردن دادهها قبل از نمایش (مثلاً افزودن واحد، تغییر فرمت عدد).
- اعمال عملیات پیچیده روی هر مقدار که نیاز به کلید (key) دارد.
- تزریق پارامترهای مشترک به callback (با پارامتر userdata).
- اجرای عملیات جانبی مانند لاگبرداری برای هر عنصر.
نکات حرفهای و نکات عملکردی
- برای آرایههای بسیار بزرگ،
foreachمعمولاً خواناتر و در برخی موارد سریعتر است. اگر تنها میخواهید مقادیر را تغییر دهید و خوانایی مهم است، از foreach با مرجع استفاده کنید. - آرگومان
$userdataهنگام استفاده از توابع متعددی که نیاز به پارامتر ثابت دارند مفید است؛ اما اگر closure از خارج اسکوپ متغیر را میگیرد، ممکن است نیازی به userdata نباشد (مثلاً استفاده از use در closure). - در PHP نسخههای جدید میتوانید از arrow functions استفاده کنید اما برای تغییر مقدار باید مرجع بگیرید که با arrow ممکن است پیچیدهتر شود؛ بهتر است از anonymous function با
&$valueاستفاده کنید. - هرگز روی ساختار آرایه (کلیدها) داخل callback حساب نکنید — رفتار غیرقابل پیشبینی است. از foreach برای افزودن/حذف عناصر استفاده کنید.
مثال پیشرفته: ترکیب با object و متدها
$data = ['a'=>1, 'b'=>2, 'c'=>3];
class Processor {
public function multiply(&$value, $key, $factor) {
$value *= $factor;
}
}
$p = new Processor();
array_walk($data, [$p, 'multiply'], 10);
print_r($data);
در این مثال از یک متد شیء به عنوان callback استفاده شده و فاکتور ضرب (10) از طریق userdata ارسال میشود. نتیجه مقادیر آرایه درجا ضرب میشوند.
جمعبندی و نکات نهایی
تابع array_walk() ابزار مناسبی برای اعمال تغییرات و پردازشهای درجا روی مقادیر آرایه است، بهخصوص زمانی که نیاز به دسترسی به کلیدها یا ارسال پارامتر اضافی دارید. با این حال برای تغییر ساختار آرایه یا برای عملکرد بهتر روی آرایههای خیلی بزرگ، ممکن است foreach یا توابع دیگر مناسبتر باشند.
در انتخاب بین array_walk، array_map، و foreach به هدف نهایی (درجا تغییر یا تولید آرایه جدید)، خوانایی کد و پیچیدگی عملکرد توجه کنید. بهخاطر داشته باشید که برای تغییر مقدار در آرایه از مرجع استفاده کنید و در صورت کار با آرایههای تو در تو از array_walk_recursive بهره ببرید.
آیا این مطلب برای شما مفید بود ؟



