(PHP 4, PHP 5, PHP 7, PHP 8)
in_array — Indique si une valeur appartient à un tableau
Recherche needle
dans haystack
en utilisant une comparaison
souple à moins que strict
ne soit utilisé.
needle
La valeur recherchée.
Note:
Si
needle
est une chaîne de caractères, la comparaison est faite en tenant compte de la casse.
haystack
Le tableau.
strict
Si le troisième paramètre strict
est définit à
true
alors la fonction in_array() vérifiera aussi que le type
du paramètre needle
correspond au type de la valeur trouvée dans haystack
.
Note:
Avant PHP 8.0.0, un
string
needle
correspondra à une valeur de tableau de0
en mode non strict et vice versa. Cela peut conduire à des résultats non souhaitables. Des cas particuliers similaires existent également pour d'autres types. Si vous n'êtes pas absolument certain des types de valeurs concernés, utilisez toujours le drapeaustrict
pour éviter tout comportement inattendu.
Exemple #1 Exemple avec in_array()
<?php
$os = array("Mac", "NT", "Irix", "Linux");
if (in_array("Irix", $os)) {
echo "Got Irix";
}
if (in_array("mac", $os)) {
echo "Got mac";
}
?>
La seconde condition échoue, car in_array() est sensible à la casse. Le script retourne :
Got Irix
Exemple #2 Exemple avec in_array() et le mode strict
<?php
$a = array('1.10', 12.4, 1.13);
if (in_array('12.4', $a, true)) {
echo "'12.4' est trouvé avec le mode strict\n";
}
if (in_array(1.13, $a, true)) {
echo "1.13 est trouvé avec le mode strict\n";
}
?>
L'exemple ci-dessus va afficher :
1.13 est trouvé avec le mode strict
Exemple #3 Exemple avec in_array() et un tableau en paramètre
<?php
$a = array(array('p', 'h'), array('p', 'r'), 'o');
if (in_array(array('p', 'h'), $a)) {
echo "'ph' a été trouvé\n";
}
if (in_array(array('f', 'i'), $a)) {
echo "'fi' was found\n";
}
if (in_array('o', $a)) {
echo "'o' a été trouvé\n";
}
?>
L'exemple ci-dessus va afficher :
'ph' a été trouvé 'o' a été trouvé
Loose checking returns some crazy, counter-intuitive results when used with certain arrays. It is completely correct behaviour, due to PHP's leniency on variable types, but in "real-life" is almost useless.
The solution is to use the strict checking option.
<?php
// Example array
$array = array(
'egg' => true,
'cheese' => false,
'hair' => 765,
'goblins' => null,
'ogres' => 'no ogres allowed in this array'
);
// Loose checking -- return values are in comments
// First three make sense, last four do not
in_array(null, $array); // true
in_array(false, $array); // true
in_array(765, $array); // true
in_array(763, $array); // true
in_array('egg', $array); // true
in_array('hhh', $array); // true
in_array(array(), $array); // true
// Strict checking
in_array(null, $array, true); // true
in_array(false, $array, true); // true
in_array(765, $array, true); // true
in_array(763, $array, true); // false
in_array('egg', $array, true); // false
in_array('hhh', $array, true); // false
in_array(array(), $array, true); // false
?>
Here is a recursive in_array function:
<?php
$myNumbers = [
[1,2,3,4,5],
[6,7,8,9,10],
];
$array = [
'numbers' => $myNumbers
];
// Let's try to find number 7 within $array
$hasNumber = in_array(7, $array, true); // bool(false)
$hasNumber = in_array_recursive(7, $array, true); // bool(true)
function in_array_recursive(mixed $needle, array $haystack, bool $strict): bool
{
foreach ($haystack as $element) {
if ($element === $needle) {
return true;
}
$isFound = false;
if (is_array($element)) {
$isFound = in_array_recursive($needle, $element, $strict);
}
if ($isFound === true) {
return true;
}
}
return false;
}
I'm not sure why PHP doesn't provide a way to specify a binary search. Here's an example of the performance gains, for this array size, about 50x improvement using interpreted PHP. If built in, it could probably achieve around 1000x improvement, again for this array size.
<?php
// Set up sorted array
$X = array(1);
for ($j = 1; $j < 50000; ++$j)
$X[] = $X[$j - 1] + rand(1, 6);
// Using in_array
$x = -microtime(true);
$m = 0;
for ($j = 0; $j < 10000; ++$j)
$m += in_array(rand(1, 175000), $X);
$x += microtime(true);
echo $x.PHP_EOL;
// Using binarySearch
$x = -microtime(true);
$m = 0;
for ($j = 0; $j < 10000; ++$j)
$m += binarySearch($X, rand(1, 175000));
$x += microtime(true);
echo $x.PHP_EOL;
function binarySearch($array, $value) {
$low = 0;
$high = count($array) - 1;
while ($low <= $high) {
$pivot = floor(($low + $high) / 2);
if ($array[$pivot] == $value)
return true;
if ($value < $array[$pivot])
$high = $pivot - 1;
else
$low = $pivot + 1;
}
// No match
return false;
}
/* Sample outputs, first is in_array, second is binarySearch
1.3544600009918
0.026464939117432
1.6158990859985
0.033976078033447
1.5184400081635
0.026461124420166
*/
I found out that in_array will *not* find an associative array within a haystack of associative arrays in strict mode if the keys were not generated in the *same order*:
<?php
$needle = array(
'fruit'=>'banana', 'vegetable'=>'carrot'
);
$haystack = array(
array('vegetable'=>'carrot', 'fruit'=>'banana'),
array('fruit'=>'apple', 'vegetable'=>'celery')
);
echo in_array($needle, $haystack, true) ? 'true' : 'false';
// Output is 'false'
echo in_array($needle, $haystack) ? 'true' : 'false';
// Output is 'true'
?>
I had wrongly assumed the order of the items in an associative array were irrelevant, regardless of whether 'strict' is TRUE or FALSE: The order is irrelevant *only* if not in strict mode.
I got an unexpected behavior working with in_array. I'm using following code:
<?php
// ...
$someId = getSomeId(); // it gets generated/fetched by another service, so I don't know what value it will have. P.S.: it's an integer
// The actual data in my edge-case scenario:
// $someId = 0;
// $anyArray = ['dataOne', 'dataTwo'];
if (in_array($someId, $anyArray)) {
// do some work
}
// ...
?>
With PHP7.4, in_array returns boolean true.
With PHP8.1, in_array returns boolean false.
It took me quite some time to find out what's going on.