ویژگی تصویر

تابع array_walk() در PHP — مروری جامع

  /  PHP   /  تابع array_walk() در PHP
بنر تبلیغاتی الف
آموزش 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 بهره ببرید.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: