Why in_array
not work on array that create from loop php ?
this below code show Match found
.
<?php
for ($i = 0; $i < 10; ++$i) {
$people[] = $i;
}
if (in_array('test', $people))
{
echo "Match found";
}
else
{
echo "Match not found";
}
?>
and this below code show Match not found
.
<?php
$people = array("0","1","2","3","4","5","6","7","8","9");
if (in_array('test', $people))
{
echo "Match found";
}
else
{
echo "Match not found";
}
?>
How to solve first code to show Match not found
You just change
$people[] = $i; ---by--> $people[] = "$i";
Then you compare strings
<?php
for ($i = 0; $i < 10; ++$i) {
$people[] = "$i";
}
if (in_array('test', $people))
{
echo "Match found";
}
else
{
echo "Match not found";
}
?>
Because in your first array you have integers and by default in_array()
does a non-strict type comparison, which has only a limited amount of type pairs which it takes into consideration. So it will do a silent cast to an integer with your needle, which results in 0 and it finds it in the array.
To avoid this error, just pass TRUE
as 3rd argument to in_array()
so it does a strict type comparison, e.g.
if (in_array('test', $people, TRUE))
You've already got answers that tell you how to get around this. Let me just add a more technical answer why this happens....
This behaviour is rooted in the peculiar way ZEND_API int compare_function(..)
works.
When you call in_array(needle, haystack, strict)
without $strict=true this function is used to compare needle
with every element in haystack until a match is found.
Your needle is a string and the elements in haystack are integers.
Let's take a(n abbreviated) look at compare_function()
while(1) {
switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
case TYPE_PAIR(IS_LONG, IS_LONG):
ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
return SUCCESS;
[...more CASEs that don't apply on the first iteration of the while-loop...]
default:
[...some if-elseif cases that do not apply on the first iteration of the while-loop...]
} else {
zendi_convert_scalar_to_number(op1, op1_copy, result);
zendi_convert_scalar_to_number(op2, op2_copy, result);
converted = 1;
}
[...]
when this code is exectued for the first time op1 ~ 'test'
and op2~0
. ( ~ meaning "roughly is", because the internal represenation is a little bit different, but it doesn't really matter here.)
But there is no case for the TYPE_PAIR(IS_STRING, IS_LONG), so it hits the default: branch. There are some if-conditions for handling objects, but neither operand is an object, so it get's to the part where the operands are converted (once).
Again no if-conditon applies, so it hits the last else-branch which converts both operands into numbers.'test'
gets converted to 0
and 0
stays 0
.
Then the while-loop is executed again, now with the TYPE_PAIR(IS_LONG,IS_LONG) - the very first case. And now both operands are equal -> in_array() returns true.
...and yes, I find that confusing, too ;-)