I'm getting the strange output from in_array function [duplicate] - php

This question already has answers here:
PHP in_array() / array_search() odd behaviour
(2 answers)
Closed 6 years ago.
in php the following code returns true
$array = array(
'isReady' => false,
'isPHP' => true,
'isStrange' => true
);
var_dump(in_array('sitepoint.com', $array));
result is a true WHY ?

Because of the 3rd parameter to in_array, $strict.
bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
By default it's FALSE, which makes it use ==.
'sitepoint.com' == true
That's actually true (because of PHP's type juggling)!
You want to do:
in_array('sitepoint.com', $array, TRUE);
That will make it use ===.
'sitepoint.com' === true
That's not true.

in_array performs loose comparison (value checking only, not type & value). Since your array values are all booleans (true and false), the search string ("sitepoint.com") is being coerced to a boolean, effectively, your code translates to:
var_dump(in_array((bool)'sitepoint.com', array(true, false, true)));
Since a string, when cast to bool is true, in_array returns true.
To force type and value checking, pass true as third argument to in_array.
cf the docs

Related

Is this a bug in PHP arrays? [duplicate]

I have found some odd behaviour while I was using the PHP function in_array(). I have an array like this:
$arr = [TRUE, "some string", "something else"];
Now if I want to check if "test" is in the array it is clearly not, but in_array() still returns TRUE, why is that?
$result = in_array("test", $arr);
var_dump($result); //Output: bool(true)
The same thing happens when using array_search():
$result = array_search("test", $arr);
var_dump($result); //Output: int(0)
I thought maybe that the value TRUE in the array was automatically causing the function to return TRUE for every result without checking the rest of the array, but I couldn't find any documentation that would suggest that very odd functionality.
This behaviour of the function in_array() and array_search() is not a bug, but instead well documented behaviour.
Both functions have a 3rd optional parameter called $strict which by default is FALSE:
bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
mixed array_search ( mixed $needle , array $haystack [, bool $strict = false ] )
Now what that means is that by default both functions use loosely(==) comparison to compare the values. So they only check if the values are the same after PHP type juggling and without checking the type. Because of that in your example TRUE == "any none emtpy string" evaluates to TRUE.
So by setting the 3rd parameter to TRUE while calling the function you say that PHP should use strict(===) comparison and it should check value AND type of the values while comparing.
See this as a reference: How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ?
You are right, the boolean can indeed cause this. Set the strict flag in the in_array function, this way also the type of the element is checked (basically the same as using ===):
if (in_array("username", $results, true)) // do something
if (in_array("password", $results, true)) // do something
if (in_array("birthday", $results, true)) // do something

Why does php in_array return true for an unmatched string value? Is this a bug? [duplicate]

I have found some odd behaviour while I was using the PHP function in_array(). I have an array like this:
$arr = [TRUE, "some string", "something else"];
Now if I want to check if "test" is in the array it is clearly not, but in_array() still returns TRUE, why is that?
$result = in_array("test", $arr);
var_dump($result); //Output: bool(true)
The same thing happens when using array_search():
$result = array_search("test", $arr);
var_dump($result); //Output: int(0)
I thought maybe that the value TRUE in the array was automatically causing the function to return TRUE for every result without checking the rest of the array, but I couldn't find any documentation that would suggest that very odd functionality.
This behaviour of the function in_array() and array_search() is not a bug, but instead well documented behaviour.
Both functions have a 3rd optional parameter called $strict which by default is FALSE:
bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
mixed array_search ( mixed $needle , array $haystack [, bool $strict = false ] )
Now what that means is that by default both functions use loosely(==) comparison to compare the values. So they only check if the values are the same after PHP type juggling and without checking the type. Because of that in your example TRUE == "any none emtpy string" evaluates to TRUE.
So by setting the 3rd parameter to TRUE while calling the function you say that PHP should use strict(===) comparison and it should check value AND type of the values while comparing.
See this as a reference: How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ?
You are right, the boolean can indeed cause this. Set the strict flag in the in_array function, this way also the type of the element is checked (basically the same as using ===):
if (in_array("username", $results, true)) // do something
if (in_array("password", $results, true)) // do something
if (in_array("birthday", $results, true)) // do something

Why in_array function return TRUE when we are looking for an empty string? [duplicate]

This question already has answers here:
PHP in_array() / array_search() odd behaviour
(2 answers)
Closed 6 years ago.
Could someone explain to me why that is true?
in_array('', array(0,1,2));
Because, as said in the docs:
bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
Searches haystack for needle using loose comparison unless strict is set.
... and '' == 0 is true in PHP. If you want to use strict comparison, just call in_array() with three params:
in_array('', array(0, 1, 2), true); // false
... so the types will be checked as well, and String '' won't have a chance to match against Numbers.
in_array by default performs loose comparison. Thus '' is equivalent to 0.
There is third argument (boolean) to in_array function which says if the matching is to be performed in STRICT way or not.
if you do in_array('', array(0,1,2), TRUE); then the result will be false.
Refer the documentation

PHP's variable type leniency

The most recent comment on PHP's in_array() help page (http://uk.php.net/manual/en/function.in-array.php#106319) states that some unusual results occur as a result of PHP's 'leniency on variable types', but gives no explanation as to why these results occur. In particular, I don't follow why these happen:
// Example array
$array = array(
'egg' => true,
'cheese' => false,
'hair' => 765,
'goblins' => null,
'ogres' => 'no ogres allowed in this array'
);
// Loose checking (this is the default, i.e. 3rd argument is false), return values are in comments
in_array(763, $array); // true
in_array('hhh', $array); // true
Or why the poster thought the following was strange behaviour
in_array('egg', $array); // true
in_array(array(), $array); // true
(surely 'egg' does occur in the array, and PHP doesn't care whether it's a key or value, and there is an array, and PHP doesn't care if it's empty or not?)
Can anyone give any pointers?
763 == true because true equals anything not 0, NULL or '', same thing for array because it is a value (not an object).
To circumvent this problem you should pass the third argument as TRUE to be STRICT and thus, is_rray will do a === which is a type equality so then
763 !== true
and neither will array() !== true
Internally, you can think of the basic in_array() call working like this:
function in_array($needle, $haystack, $strict = FALSE) {
foreach ($haystack as $key => $value) {
if ($strict === FALSE) {
if ($value == $needle) {
return($key);
}
} else {
if ($value === $needle) {
return($key);
}
}
return(FALSE);
}
note that it's using the == comparison operator - this one allows typecasting. So if your array contains a simple boolean TRUE value, then essentially EVERYTHING your search for with in_array will be found, and almost everything EXCEPT the following in PHP can be typecast as true:
'' == TRUE // false
0 == TRUE // false
FALSE == TRUE // false
array() == TRUE // false
'0' == TRUE // false
but:
'a' == TRUE // true
1 == TRUE // true
'1' == TRUE // true
3.1415926 = TRUE // true
etc...
This is why in_array has the optional 3rd parameter to force a strict comparison. It simply makes in_array do a === strict comparison, instead of ==.
Which means that
'a' === TRUE // FALSE
PHP treating arrays as primitive values is a constant source of pain as they can be very complex data structures, it doesn't make any sense. For example, if you assign array to something, and then modify the array, the original isn't modified, instead it is copied.
<?php
$arr = array(
"key" => NULL
);
var_dump( array() == NULL ); //True :(
var_dump( in_array( array(), $arr ) ); //True, wtf? It's because apparently array() == NULL
var_dump( in_array( new stdClass, $arr ) ); //False, thank god
?>
Also, 'egg' is not a value in the array, it's a key, so of course it's surprising that it would return true. This kind of behavior is not ok in any other language I know about, so it will trip over many people who don't know php quirks inside out.
Even a simple rule that an empty string is falsy, is violated in php:
if( "0" ) {
echo "hello"; //not executed
}
"0" is a non-empty string by any conceivable definition, yet it is a falsy value.

how to check if an array has value that === null without looping?

http://php.net/manual/en/function.in-array.php - has issues with that since it checks only by ==. Is there any clever oneliner here that can do it by === ?
That is to return false if an array is empty, that is has 0 elements, or when array doesn't contain any value that is exactly null. True if array has at least one === null element.
in_array(null, $haystack, true);
If you read the doc you referenced, you'll see that that function takes an optional third parameter:
If the third parameter strict is set
to TRUE then the in_array() function
will also check the types of the
needle in the haystack.
Here is the function signature, specifically as it appears in the doc:
bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
Searches haystack for needle using loose comparison unless strict is set.
The in_array function accepts a third param (strict) that will do === comparison
in_array(null, $array, true);

Categories