Signature
array_filter(array $array, ?callable $callback = null, int $mode = 0): arrayPurpose
array_filter() walks over an array and builds a new array that contains only the elements you want to keep. You decide what to keep with a callback that returns a truthy or falsy result. If you omit the callback, PHP removes every element that counts as empty. The original array is never modified; you always get a fresh array back.
Signature
Parameters and defaults
$array: the array to iterate over.$callback: a function called for each element. If it returns a truthy value, the element is copied into the result. The default isnull, which means no callback is used and each value is checked the wayempty()would check it.$mode: controls what the callback receives. The default0passes only the value.ARRAY_FILTER_USE_KEYpasses only the key.ARRAY_FILTER_USE_BOTHpasses the value first and the key second. When$callbackisnull, the mode is ignored.
Return value and failure cases
The function returns an array, possibly an empty one when nothing passes the test. Keys are preserved, so a filtered list can contain gaps in its numeric keys. Call array_values() on the result when you need a tidy, zero-based list.
Passing something that is not callable as $callback raises a TypeError. Since PHP 8.0.0 the callback is nullable, and a callback that expects a parameter by reference triggers an E_WARNING. The manual also warns that changing the array from inside the callback, such as adding or unsetting elements, gives undefined behavior, so keep callbacks free of side effects.
Example 1: filtering by value
The callback receives each value in turn. Notice that the surviving elements keep their original keys, and that array_values() renumbers them.
$numbers = [1, 2, 3, 4, 5, 6];
$even = array_filter($numbers, fn(int $n): bool => $n % 2 === 0);
echo json_encode($even), "\n";
echo json_encode(array_values($even)), "\n";{"1":2,"3":4,"5":6}
[2,4,6]
Because the keys 1, 3 and 5 survive, JSON encodes the first result as an object rather than a list.
Example 2: filtering without a callback
Without a callback, every falsy value is removed. This includes false, null, 0, the empty string, the string '0' and an empty array. Strings such as '0.0' are not falsy and stay.
$entry = ['foo', false, -1, null, '', '0', 0, [], '0.0'];
echo json_encode(array_filter($entry), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"0":"foo","2":-1,"8":"0.0"}
This is handy for cleaning up form-like input, but be careful: a legitimate 0 is removed along with the junk.
Example 3: using keys with the mode flag
With ARRAY_FILTER_USE_KEY the callback sees only the key. With ARRAY_FILTER_USE_BOTH it sees the value and then the key, so the parameter order is $value, $key.
$prices = ['apple' => 120, 'banana' => 80, 'cherry' => 300, 'avocado' => 150];
$byKey = array_filter($prices, fn(string $key): bool => str_starts_with($key, 'a'), ARRAY_FILTER_USE_KEY);
$both = array_filter($prices, fn(int $price, string $key): bool => $price >= 100 && $key !== 'apple', ARRAY_FILTER_USE_BOTH);
echo json_encode($byKey), "\n";
echo json_encode($both), "\n";{"apple":120,"avocado":150}
{"cherry":300,"avocado":150}
Edge cases
- An empty input array returns an empty array.
- If no element passes, the result is an empty array, not
false. - The callback result is judged for truthiness, so returning
1,"yes"ortrueall keep the element. Returning0ornulldrops it. A bitwise expression such as$n & 1works, but an explicit boolean is clearer. - Numeric-looking string keys are stored as integers in PHP arrays. With
ARRAY_FILTER_USE_KEY, a callback that declares astringkey type may behave unexpectedly in strict-types code, so use no type or a union such asint|stringwhen keys can be mixed. - The relative order of the surviving elements stays the same.
Common mistakes
- Expecting a reindexed list. After filtering, indexes may have gaps. Wrap the call in
array_values()before encoding as a JSON list or accessing[0]. - Using no callback on data where zero is valid. Quantities, scores and prices of
0vanish. Supply a callback such asfn($v) => $v !== nullto remove only what you intend. - Mixing up the parameter order in
ARRAY_FILTER_USE_BOTH. The value comes first, the key second. - Forgetting the mode flag. Without it, a callback written for keys receives values instead.
- Modifying the array inside the callback. The behavior is undefined; compute the changes separately.
- Using it to transform values.
array_filter()only selects; it never changes the elements. Usearray_map()for transformation.
Related functions
array_values()renumbers keys after filtering.array_map()transforms every element.array_reduce()collapses an array to a single value.array_find()returns the first element satisfying a callback.array_any()tells you whether at least one element satisfies a callback.array_intersect()keeps values that also appear in other arrays.
Recap
array_filter() returns a new array holding only elements that pass your test. Keys are preserved, so reindex with array_values() when order matters more than keys. With no callback it removes all falsy values, and the mode argument lets the callback inspect keys, or both values and keys.
Tested examples
$numbers = [1, 2, 3, 4, 5, 6];
$even = array_filter($numbers, fn(int $n): bool => $n % 2 === 0);
echo json_encode($even), "\n";
echo json_encode(array_values($even)), "\n";{"1":2,"3":4,"5":6}
[2,4,6]
$entry = ['foo', false, -1, null, '', '0', 0, [], '0.0'];
echo json_encode(array_filter($entry), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"0":"foo","2":-1,"8":"0.0"}
$prices = ['apple' => 120, 'banana' => 80, 'cherry' => 300, 'avocado' => 150];
$byKey = array_filter($prices, fn(string $key): bool => str_starts_with($key, 'a'), ARRAY_FILTER_USE_KEY);
$both = array_filter($prices, fn(int $price, string $key): bool => $price >= 100 && $key !== 'apple', ARRAY_FILTER_USE_BOTH);
echo json_encode($byKey), "\n";
echo json_encode($both), "\n";{"apple":120,"avocado":150}
{"cherry":300,"avocado":150}