Why is in_array()
sometimes behaving so strangely and returns such unexpected results?
Let's have a look at a few examples:
$arrayWithTrue = ['Andreas', 'Philipp', true];
$arrayWithNull = [1, 2, 3, null];
$arrayWithMinusOne = [-1];
var_dump(in_array('Gary', $arrayWithTrue)); // returns bool(true)
var_dump(in_array(0, $arrayWithNull)); // returns bool(true)
var_dump(in_array(true, $arrayWithMinusOne)); // returns bool(true)
Huh? What's happening here!?
(Some years ago I wondered about this, at first, strange behaviour. I thought it might be useful for some people though, thus I entered this question.)
The in_array() function is an inbuilt function in PHP that is used to check whether a given value exists in an array or not. It returns TRUE if the given value is found in the given array, and FALSE otherwise.
The in_array() function searches an array for a specific value. Note: If the search parameter is a string and the type parameter is set to TRUE, the search is case-sensitive.
Use in_array()
always with the third parameter strict true
:
$arrayWithTrue = ['Andreas', 'Philipp', true];
$arrayWithNull = [1, 2, 3, null];
$arrayWithMinusOne = [-1];
var_dump(in_array('Gary', $arrayWithTrue, true)); // returns bool(false)
var_dump(in_array(0, $arrayWithNull, true)); // returns bool(false)
var_dump(in_array(true, [-1], true)); // returns bool(false)
So when you use in_array()
with true
as third parameter, the comparison between the searched value and the array is done strictly, meaning in_array()
works like you would probably expect it.
(The parameter strict is also described in the php.net documentation.)
Without the parameter strict set to true, the comparison between the searched value and each value of the array is done by equality and not by identity. This means that the value's type does not matter and thus PHP converts the values internally to the same data type in order to be able to compare them.
This means that in the first example, the searched value 'Gary'
is converted to a boolean when it's compared with true
, so it results in the comparison of true
with true
, which is obviously true
.
The same goes with the second array, where 0
is finally compared with null
, resulting in true
, even though 0
is obviously not the same as null
(this can be especially tricky when you work with numbers and / or function results for example, where null
can express an empty value and not 0
).
The third array then looks really weird, because we check for the value true
in the array, which only contains -1
, but in_array()
still returns true
for the comparison. In this case the -1
gets converted to a boolean true
. So the problem is the same in both directions.
You can find more examples about the comparison problem in PHP (because this is the same as ==
/ ===
) in this Stack Overflow answer.
Unfortunately, the default for the strict parameter when calling in_array()
is... well, yeah, false
. :-/ PHP and it's typing...
You should really never ever call in_array()
without the strict parameter set to true
. When you do not have arrays of mixed types and you only check the values with the same type, in_array()
works as expected. See this example:
$arrayWithStrings = ['Andreas', 'Philipp', 'Friedrich'];
var_dump(in_array('Gary', $arrayWithStrings)); // returns bool(false)
So at least this works as expected. But in my opinion, it is much easier to just always call in_array()
with strict true
. (Similiar to the "SQL Injection Problem"... Just always use PDO and prepared statements so you're safe, even though it's a query without variable parameters. You're always safe then.)
You should definitely call in_array()
with strict true
. But there is one downside though, I do want to mention (even though it is obvious). You must definitely use the correct types when calling in_array()
then:
$arrayWithNumbers = [1, 2, 3];
var_dump(in_array('1', $arrayWithNumbers, true)); // returns bool(false)
But you can just use Type Casting, when you know that you compare numbers:
$arrayWithNumbers = [1, 2, 3];
var_dump(in_array((int)'1', $arrayWithNumbers, true)); // returns bool(true)
// Comparing false with an empty array
var_dump(in_array(false, [[]])); // returns bool(true)
Well, yeah... Just use it with strict set to true
. ;-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With