In PHP, will these always return the same values?
//example 1
$array = array();
if ($array) {
echo 'the array has items';
}
// example 2
$array = array();
if (count($array)) {
echo 'the array has items';
}
Thank you!
From http://www.php.net/manual/en/language.types.boolean.php, it says that an empty array is considered FALSE.
(Quoted):
When converting to boolean, the following values are considered FALSE:
the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
an object with zero member variables (PHP 4 only)
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
Since
a count() of > 0 IS NOT FALSE
a filled array IS NOT FALSE
then both cases illustrated in the question will always work as expected.
Those will always return the same value, but I find
$array = array();
if (empty($array)) {
echo 'the array is empty';
}
to be a lot more readable.
Note that the second example (using count()) is significantly slower, by at least 50% on my system (over 10000 iterations). count() actually counts the elements of an array. I'm not positive, but I imagine casting an array to a boolean works much like empty(), and stops as soon as it finds at least one element.
Indeed they will. Converting an array to a bool will give you true if it is non-empty, and the count of an array is true with more than one element.
See also: http://ca2.php.net/manual/en/language.types.boolean.php#language.types.boolean.casting
Related
Why does the following code work:
$test = array(0=>'test1','field0'=>'test2',1=>'test3','field1'=>'test4');
echo array_search('test4',$test);
But the following doesn't:
$test = array(0=>0,'field0'=>'test2',1=>'test3','field1'=>'test4');
echo array_search('test4',$test);
If you had a mixed array from say mysql_fetch_array($result,MYSQL_BOTH) and took the keys which you needed to search you wouldn't be able too - it would never progress further than 0.
Try to do array_search('test4',$test, TRUE);. The 3rd parameter tells it to use === instead of == when comparing.
Since your array holds both strings and numbers, when it compares to the 0 (the 1st element), it converts 'test4' to a number (it stops at the 1st non-numeric character) and it happens to match.
What I mean is: 'test4' == 0 => 0 == 0 => true.
When you pass TRUE as the 3rd parameter, it uses ===, and 'test4' === 0 is automatically false since the types don't match, there is no conversion.
The solution = force the 0 value to be a string:
$test = array(0=>0,'field0'=>'test2',1=>'test3','field1'=>'test4');
foreach ($test as $k=>$v){ $test[$k] = (string) $v; }
echo array_search('test4',$test);
You can't search a number for a string and expect a good result.
My guess is it sees the value as a number, so it converts your string to a number (which it can't) so that string gets converted to a 0. So the value of 0 equals the search string, which also equals 0, and there's your result.
If the value is 1, it won't match as the search string gets converted to a 0 (as you can't convert a string to a number) so it wouldn't match in the following.
$test = array(0=>1,'field0'=>'test2',1=>'test3','field1'=>'test4');
You'll only get your exact case scenario when that value in the array is 0.
I was trying to understand the in_array behavior at the next scenario:
$arr = array(2 => 'Bye', 52, 77, 3 => 'Hey');
var_dump(in_array(0, $arr));
The returned value of the in_array() is boolean true. As you can see there is no value equal to 0, so if can some one please help me understand why does the function return true?
This is a known issue, per the comments in the documentation. Consider the following examples:
in_array(0, array(42)); // FALSE
in_array(0, array('42')); // FALSE
in_array(0, array('Foo')); // TRUE
To avoid this, provide the third paramter, true, placing the comparison in strict mode which will not only compare values, but types as well:
var_dump(in_array(0, $arr, true));
Other work-arounds exist that don't necessitate every check being placed in strict-mode:
in_array($value, $my_array, empty($value) && $value !== '0');
But Why?
The reason behind all of this is likely string-to-number conversions. If we attempt to get a number from "Bye", we are given 0, which is the value we're asking to look-up.
echo intval("Bye"); // 0
To confirm this, we can use array_search to find the key that is associated with the matching value:
$arr = array(2 => 'Bye', 52, 77, 3 => 'Hey');
echo array_search(0, $arr);
In this, the returned key is 2, meaning 0 is being found in the conversion of Bye to an integer.
Try adding a third parameter true (strict mode) to your in_array call.
This is a result of the loose comparison and type juggling.
Loose comparison means that PHP is using == not === when comparing elements. == does not compare that the two variable types are equal, only their value, while === will ensure that they match in type and value (e.g. compare 0 == FALSE and 0 === FALSE).
So, basically, your in_array function is checking:
0 == 'Bye'
0 == 'Hey'
0 == 77
Note that the 52 will get lost due to the way you created your array.
So, note that if you do:
print (0 == 'Bye');
You will get 1. Apparently, PHP is type juggling the 'Bye' to 0, which is the same thing that will happen when you cast a string to an int, e.g. (int) 'string' will equal 0. Specific reference from the String conversion to numbers doc (Emphasis added):
The value is given by the initial portion of the string. If the string
starts with valid numeric data, this will be the value used.
Otherwise, the value will be 0 (zero). Valid numeric data is an
optional sign, followed by one or more digits (optionally containing a
decimal point), followed by an optional exponent. The exponent is an
'e' or 'E' followed by one or more digits.
Apparently, the integer type takes precedence over the string type (i.e. it could just as easily be doing the comparison by casting the int 0 to a string, which would then return False). This is specified in the comparison operators doc:
If you compare a number with a string or the comparison involves
numerical strings, then each string is converted to a number and the
comparison performed numerically.
Thanks for an interesting question that led me to do some research and learn something new!
in_array is supposed to be used on indexed arrays ([0], [1], [2] etc), not with a dictionary as you have defined (key-value store).
If you want to check if your array $arr includes '0', try using the PHP function array_key_exists instead - http://php.net/manual/en/function.array-key-exists.php.
var_dump(array_key_exists(0, $arr));
Type compare (third parameter) needs more system resources and more time.
Simply do that:
$x=0;
$result=in_array($x.'',array('ABC','BAC','12c','54'));
var_dump($result);
For some reason when I iterate through an array using foreach loop a condition fails comparing the key with a string. My array has two indexes the first one is an integer and the second one is an string.
$firmas[] = $credito['acreditado'];
$firmas['cbi'] = "LIC. MARCELA SOTO ALARCĂ“N";
I want to do something else when the loop finds that the key in that moment is the string one but for some reason when I evaluate the integer index the result is true.
foreach($firmas as $key => $firma){
var_dump($key);
var_dump($key=='cbi');die();
}
The output is
int(0) bool(true)
But as you can see the condition is looking for the string 'cbi' so the result should be false with the integer index and true for the string.
What's happening here?
In PHP, all strings are equal to 0, though not equivalent to it. Try using === instead of just ==.
Addendum: all strings that do not begin with numbers are equal to 0.
I need to have an array_search search my array strictly making sure that the item is identical (meaning the whole thing is the same thing as the input value). I know about the third variable in a array_search() function in PHP - the Strict one, but I don't want it to check if its the same instance, as it is not. How would I do this?
Here is the code I'm currently using:
array_search(some, array(someItem,anothervariable, yetanothervariable, some));
//output - 0 (the first item) which contains some but isn't exactly some.
Requested output:
Instead of outputting the first item that contains some, someItem, it would output the key for the last item, 3, that is the exact search value.
Array search with strict is equivalent to the === operator.
Array search without strict is equivalent to the == operator.
If you need some sort of special comparison that isn't covered by either of them (comparing elements of objects for example) then you need to write a loop.
Are you open to using a foreach loop instead of array_search?
If so try this:
$haystack = array('something', 'someone', 'somewhere', 'some');
$needle = 'some';
foreach($haystack as $key=>$straw){
if($straw === $needle){
$straws[$key] = $straw;
}
}
print_r($straws);
it will print
Array ( [3] => some )
Or you could use array_keys() with the search value specified.
Then, using the same $haystack and $needle above:
$result = array_keys($haystack,$needle,TRUE);
print_r($result);
This returns:
Array ( [0] => 3 )
The first argument is the array to return keys from, The second arg is the search value, if you include this arg, then only keys from array elements that match the search value are returned. Including the third boolean arg tells the function to use match type as well (===).
Not really sure what you are asking but in PHP strict comparison is achieved with the
triple equal sign (===). This means that both the value and the type must be the same.
So if you compare a string "1" and an integer 1 with === it will fail.
If strict is false then comparing string "1" with integer 1 would succeed.
This is the meaning of strict in the array_search case.
I implemented array_search below so you can see what it is doing.
function my_array_search($input, $search_array, $strict=false) {
if(is_array($search_array)) {
foreach($search_array as $key => $val) {
if($strict === true) {
if($val === $input) {
return $key;
}
} else {
if($val == $input) {
return $key;
}
}
}
}
}
I am using a class which returns me the value of a particular row and cell of an excel spreadsheet. To build up an array of one column I am counting the rows and then looping through that number with a for() loop and then using the $array[] = $value to set the incrementing array object's value.
This works great if none of the values in a cell are 0. The class returns me a number 0 so it's nothing to do with the class, I think it's the way I am looping through the rows and then assigning them to the array... I want to carry through the 0 value because I am creating graphs with the data afterwards, here is the code I have.
// Get Rainfall
$rainfall = array();
for($i=1;$i<=$count;$i++)
{
if($data->val($i,2) != 'Rainfall') // Check if not the column title
{
$rainfall[] = $data->val($i,2);
}
}
For your info $data is the excel spreadsheet object and the method $data->val(row,col) is what returns me the value. In this case I am getting data from column 2.
Screenshot of spreadsheet
Did you try an array_push() ?
array_push($rainfall, $data->val($i,2));
I would use a strict comparison with the not identical operator here instead of using the not equals operator:
if($data->val($i,2) !== 'Rainfall')
If $data->val($i,2) is an integer and you use == both sides will be cast to integers which would give you the result that all integers would work as you expect except for zero. Here's a summary of the difference between == and === when comparing the string "RainFall" with zero:
0 == "RainFall" : true
0 != "RainFall" : false
0 === "RainFall" : false
0 !== "RainFall" : true
I think that the array is treating the 0 like false, which could explain it not going into the array. Would something like this work (if you are using integers)?
(int)($data->val($i,2));
or
(float)($data->val($i,2);)
The problem lies in the if statement. You're trying to compare a string with an integer, which according to the PHP documentation will typecast both to integers.
If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. These rules also apply to the switch statement. The type conversion does not take place when the comparison is === or !== as this involves comparing the type as well as the value.
You can read more here http://php.net/manual/en/language.operators.comparison.php.
Update: The if statement won't work in the case of 0 because (int)"Rainfall" will by typecasted into 0 by PHP causing the statement to be if (0 != 0) { ... }.
If $i represents the row number, why don't you start from 2 instead of 1?