Advanced Array Functions
debt(d5/e3/b3/t6)
Closest to 'specialist tool catches it' (d5). Tools listed in detection_hints (phpcs, phpstan, rector) can detect patterns like manual nested loops replacing built-in array functions, misuse of array_map vs array_walk, and missing array_values() after array_filter(). However, subtle semantic errors like usort destroying associative keys or incorrect array_reduce accumulator logic may require more careful review, pushing slightly beyond default linter territory into specialist tooling.
Closest to 'simple parameterised fix' (e3). The quick_fix describes single-function replacements (e.g., swap usort for uasort, add array_values() after array_filter, fix array_reduce return). Most mistakes are localized to a single call site or a small set of related calls within one file/component. Not quite e1 because some fixes require understanding the semantic difference and may touch a few related lines.
Closest to 'localised tax' (b3). These array functions are used across all PHP contexts (web, cli, queue-worker) and are fundamental, but misuse of any single function is typically localized to the component using it. The choice doesn't impose system-wide architectural weight — it's a per-usage decision. If misused consistently it could create a pattern of bugs, but each instance is independently fixable.
Closest to 'notable trap' (t5), +1 to t6. The misconception field highlights a serious and silent trap: usort vs uasort silently destroys key associations on associative arrays. Combined with common_mistakes like array_map vs array_walk confusion (create vs modify in place), array_reduce accumulator semantics, array_combine requiring equal-count arrays, and array_filter not resetting keys — these are multiple documented gotchas that contradict intuitions from similar concepts in other languages (e.g., map/reduce in JS). The usort trap in particular contradicts expectations from languages where sort preserves structure, pushing this above a standard t5.
Also Known As
TL;DR
Explanation
Beyond array_map and array_filter, PHP provides powerful array functions for expressive data transformation. usort($arr, $fn) sorts with a custom comparator using the spaceship operator (<=>); note it reindexes numeric keys — use uasort() to preserve them. array_walk(&$arr, $fn) modifies elements in-place: the callback must accept the value by reference (&$value) for modifications to persist. array_reduce($arr, $fn, $initial) folds an array to a single value — $carry holds the accumulated result and $initial sets the starting value, making it ideal for sums, string joins, or grouping. array_column($records, 'name', 'id') extracts a column from a 2D array, optionally indexed by another column, replacing common foreach-to-map patterns. array_combine($keys, $values) zips two arrays into one associative array. array_diff_key and array_intersect_key operate on keys rather than values — powerful for allowlist/blocklist filtering of input arrays.
Watch Out
Common Misconception
Why It Matters
Common Mistakes
- Using array_map() when array_walk() is needed — map creates a new array, walk modifies in place.
- Not understanding array_reduce() carry semantics — the accumulator must be returned on each iteration.
- Using array_combine() without ensuring keys and values arrays have the same count — triggers a warning and returns false.
- Forgetting that array_filter() resets no keys — use array_values() if sequential indexing is needed after filtering.
Code Examples
// array_filter leaves gaps in numeric keys:
$filtered = array_filter([1, 2, 3, 4], fn($n) => $n > 2);
// Result: [2 => 3, 3 => 4] — not [0 => 3, 1 => 4]
// Fix: $filtered = array_values(array_filter(...));
// usort — sort by age ascending (reindexes numeric keys)
usort($users, fn($a, $b) => $a['age'] <=> $b['age']);
// Preserve keys: uasort($assoc, $fn)
// array_walk — modify in-place (& required for mutation)
array_walk($products, function (&$item, $key) {
$item['price'] = round($item['price'] * 1.2, 2); // apply 20% markup
});
// array_reduce — $carry = accumulator, 0 = initial value
$total = array_reduce(
$items,
fn($carry, $item) => $carry + $item['price'],
0
);
// array_column — build id→name map (replaces foreach)
$names = array_column($users, 'name', 'id');
// Before: $names = []; foreach ($users as $u) { $names[$u['id']] = $u['name']; }
// array_combine — zip two arrays
$lookup = array_combine($ids, $names); // [1 => 'Alice', 2 => 'Bob']
// array_diff_key — remove disallowed keys from input
$allowed = ['name' => 1, 'email' => 1, 'age' => 1];
$safe = array_intersect_key($_POST, $allowed);
// array_flip — swap keys and values
$byName = array_flip($names); // ['Alice' => 1, 'Bob' => 2]
// array_count_values — frequency map
$freq = array_count_values(['php','js','php','php','js']);
// ['php' => 3, 'js' => 2]