Searching an array
The attendant can do more than sort and pick out items: they can also find them. Ask "Do you have a blue coat?", and they answer "yes" or "no". Ask "Which hook is it on?", and they name a number.
In PHP the first question is answered by the in_array function, the second by array_search.
As you already know, the == operator compares loosely: to it the string '10' and the number 10 are the same. Both functions compare exactly that way by default:
<?php
$allowed = ['10', '20', '30'];
var_dump(in_array(10, $allowed)); // bool(true)
var_dump(in_array(10, $allowed, true)); // bool(false)
var_dump(in_array('10', $allowed, true)); // bool(true)Let's go through it line by line:
$allowedis a list of allowed codes. They are strings: that is how data usually arrives from a form or a file.in_array(10, $allowed)compares with==and finds'10', so it returnstrue, andvar_dumpprintsbool(true).- With the third argument
truethe comparison uses===. The number10is not equal to the string'10', and the answer isbool(false). - The string
'10'matches the string'10'under strict comparison too.
in_array: is the value there
in_array checks whether a value is among the array's values and returns true or false. It does not look at the keys.
Loose comparison by default
Without a third argument each value of the array is compared with the one you look for using ==. That is why in_array('1e1', $allowed) also returns true. Both strings, '1e1' and '10', are numeric, and == compares such strings as numbers: 1e1 is 10.
Strict comparison with true
The third argument true switches on ===: only a value of the same type matches. An allowlist is a list of allowed values: roles, codes, identifiers. When you check against one, always pass true, or the check also lets through '1e1', which is not on the list.
Interviewers often ask why in_array without a third argument is dangerous. The answer: it compares with ==, and values that are only loosely equal to the allowed ones get through the allowlist.
array_search: where the value is
array_search searches the same way as in_array and understands the same third argument. But it returns no "yes" or "no": it returns the key of the element it found. If the value is not there, it returns false:
$days = ['mon', 'tue', 'wed'];
var_dump(array_search('tue', $days)); // int(1)
var_dump(array_search('mon', $days)); // int(0)
var_dump(array_search('sun', $days)); // bool(false)Look at the second line. 'mon' hangs on the first hook, and that hook's number is 0. It is a real key, and yet in an if condition the number 0 is falsy, as false is.
That is why the result of array_search is compared strictly: $pos === false means "not found", and any other value is the key of a match. This is another classic interview question: "What is dangerous about if (array_search(…))?"
This is where the attendant picture falls short. A real attendant asked "where is the coat?" says "on the first hook", while array_search names the number 0, and that answer can be mistaken for "nowhere".
Key or value
in_array and array_search search among the values. A key is checked by isset and array_key_exists, and the two part ways on a null value. For $stock = ['kiwi' => null] the expression isset($stock['kiwi']) gives false, while array_key_exists('kiwi', $stock) gives true: the key is there, it holds null.
Five more helpers
PHP has ready answers to common questions about an array:
$visits = [3, 7, 3, 5, 7];
echo implode(' ', array_unique($visits)), "\n"; // 3 7 5
echo json_encode(array_unique($visits)), "\n"; // {"0":3,"1":7,"3":5}
echo max($visits), ' ', min($visits), "\n"; // 7 3
echo implode(' ', range(1, 5)), "\n"; // 1 2 3 4 5
echo array_key_first(['pear' => 7, 'kiwi' => 9]), "\n"; // peararray_uniqueremoves repeats and keeps the first occurrence of each value together with its key. So, as afterarray_filter, the numbering is left with holes.maxandminreturn the largest and the smallest value.range(1, 5)builds a list of the numbers from1to5inclusive.array_key_firstreturns the array's first key, andnullfor an empty array.
Common mistake
The result of array_search was checked with a plain condition:
$queue = ['ann', 'bob', 'cat'];
$pos = array_search('ann', $queue);
if (!$pos) { // ✗
echo 'not in the queue', "\n";
}The program prints not in the queue, although 'ann' is first in the queue, and PHP shows no message. array_search returned the key 0, and !0 is true. The fix is a strict check: if ($pos === false).
Key points
in_arrayandarray_searchcompare with==by default; the third argumenttrueswitches on===.in_arrayanswerstrueorfalse, whilearray_searchreturns the key of the element it found, orfalse.- The key
0is a real match, but it is falsy in anif, so the result ofarray_searchis checked with=== false. array_unique,max,min,rangeandarray_key_firstanswer common questions about an array in one line.