PHP array delete by value (not key): looking under the hood
\n\nImagine: you're writing a PHP script, processing a list of products, and suddenly you need to remove an item with a specific price or name from the array. You know the value exactly — for example, "apple" — but you have no idea what index it's at. Sound familiar? If so, you're not alone: the question "PHP array delete by value (not key)" gathers thousands of views on Stack Overflow. And that's no coincidence.
PHP doesn't have a built-in array_remove_by_value() function. So developers improvise: some write a loop, some use array_search paired with unset, some use array_diff or array_filter. But what happens inside? Which method is faster? And why can the same code behave differently in different PHP versions?
In this article, we won't just give you a ready-made solution — we'll look under the hood of each approach, analyze its performance and pitfalls. We'll also show a real-world case from a backend developer's life. Let's go!
\n\nThe classic way: array_search + unset
\n\nThe most popular answer on Stack Overflow looks like this:
\n\n<?php\n$array = ['apple', 'pear', 'orange', 'pear'];\n$value = 'pear';\n\nif (($key = array_search($value, $array)) !== false) {\n unset($array[$key]);\n}\n?>\n\nThis code finds the first occurrence of the value and removes it. But let's break down what's actually happening here.
\n\nHow array_search works
\n\narray_search() is a linear search. PHP goes through the array from start to finish, comparing each value with the search value. The default comparison is loose (==), meaning 1 and '1' are considered equal. If you need strict comparison (===), pass the third parameter true:
<?php\n$array = [0, '0', 1];\n$key = array_search('0', $array, true); // returns 1 (the string '0'), not 0\n?>\n\nIf the value is not found, the function returns false. Therefore, the check !== false is mandatory — otherwise unset($array[0]) would delete the first element if the value happens to have key 0.
The pitfall: unset does not re-index the array
\n\nAfter unset, the array remains associative — numeric keys are not shifted. If you need a dense array with sequential indices, use array_values():
<?php\n$array = ['apple', 'pear', 'orange'];\nunset($array[1]);\n$array = array_values($array); // ['apple', 'orange'] with keys 0 and 1\n?>\n\nBut remember: array_values() creates a new array, which increases memory consumption.
Removing all occurrences: array_diff
\n\nIf you need to remove all elements with a given value, using array_search in a loop is not the best idea. array_diff() works much more elegantly:
<?php\n$array = ['apple', 'pear', 'orange', 'pear'];\n$array = array_diff($array, ['pear']);\n// Result: ['apple', 'orange'] (keys are preserved)\n?>\n\nThe function returns a new array from which all elements matching the values in the second array have been removed. Internally, PHP uses a hash table for the second array, so the operation runs in O(n + m), where n is the size of the first array and m is the size of the second.
\n\nImportant: array_diff compares values as strings ((string) $elem1 === (string) $elem2). For mixed types, this can produce unexpected results:
<?php\n$array = [0, '0', false];\n$result = array_diff($array, [0]);\n// Result: