php comparison operator in assignment - php

I saw a small php quiz online that contained the following code:
$somevalue[[ 2 <=['-']=> 2][1]] = $somestring;
My question is, what does the part before the assignment do?
$somevalue[[ 2 <=['-']=> 2][1]]
<= looks like the comparison operator but in that case it is comparing 2 to '-'?

PHP's array initialization syntax looks like this:
$arr = [ key => value ];
So in this part:
2 <=['-']=> 2
The 'key' is the result of the expression 2 <= ['-'], which according to this page evaluates to true (an array is always greater than what you are comparing it to, unless it's another array). Because PHP arrays keys are either integers or strings, the boolean result is implicitly cast to the integer 1, so you end up with:
1 => 2
So the simplified expression:
[ 1 => 2 ][1]
Will evaluate to the second element of the array we've just created (PHP array's are 0-based), so this will simplify to:
2
So at the end we end up with:
$somevalue[2] = $somestring;

To understand this you need to break the statement in parts,
echo 2 <=['-'];//return true
PHP Comparison operator
After this the statement will be
$somevalue[[1 => 2][1]] = $somestring;
Here you see the array index 1 has values 2. After this the last index which is 1, from the array [1 => 2] it will return 2, so finally you will have
$somevalue[2] = $somestring;

Related

Does PHP's array equality require elements in the same order?

According to http://php.net/manual/en/language.operators.array.php:
$a == $b Equality TRUE if $a and $b have the same key/value pairs.
$a === $b Identity TRUE if $a and $b have the same key/value pairs in the same order and of the same types.
As such, I would have expected these two arrays to have equality, but they do not.
$a1=array('a','b');
$a2=array('b','a');
echo(($a1==$a2)?'equal':'not equal');
I could sort the arrays first and they have both equality and identity.
Am I misinterpreting the PHP manual? Does PHP's array equality require elements in the same order?
EDIT. The posted answers perfectly answered the question. Possible workarounds include the following. While not part of my original question, any recommendations on the best way to implement would be appreciated.
<?php
$a1=array('a','b');
$a2=array('b','a');
echo((($a1==$a2)?'equal':'not equal').'<br>');
echo(((array_diff($a1, $a2) === array_diff($a2, $a1))?'equal':'not equal').'<br>');
sort($a1);
sort($a2);
echo((($a1==$a2)?'equal':'not equal').'<br>');
?>
OUTPUT:
not equal
equal
equal
That's Because:
In the first array it's:
0 => a
1 => b
And in the second array it's:
0 => b
1 => a
So the values and the keys are the same, but not as pair!
So if you change the keys in the second array it's TRUE because the value and the key's are the same as pair:
$a1 = array('a','b');
$a2 = array( 1 =>'b', 0 =>'a');
echo(($a1==$a2)?'equal':'not equal');
Output:
equal
Its a good question but as the docs mention. It needs the same key value pairs. Your first array is 1 => a and your second is 2=>a
Same for b. So therefore not equal.
An example would be
$a=array('a'=>'a','b'=>'b');
$a=array('b=>'b','a'=>'a');

array_search can't find element which is clearly there

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.

strlen on array returns 5 in php

From the docs -
int strlen ( string $string )
it takes string as a parameter, now when I am doing this-
$a = array('tex','ben');
echo strlen($a);
Output -
5
However I was expecting, two type of output-
If it is an array, php might convert it into string so the array will become-
'texben' so it may output - 6
If 1st one is not it will convert it something like this -
"array('tex','ben')" so the expected output should be - 18 (count of all items)
But every time it output- 5
My consideration from the output is 5 from array word count but I am not sure. If it is the case how PHP is doing this ?(means counting 5)
The function casts the input as a string, and so arrays become Array, which is why you get a count of 5.
It's the same as doing:
$a = array('tex','ben');
echo (string)$a; // Array
var_dump((string)$a); // string(5) "Array"
This is the behavior prior to PHP 5.3. However in PHP 5.3 and above, strlen() will return NULL for arrays.
From the Manual:
strlen() returns NULL when executed on arrays, and an E_WARNING level error is emitted.
Prior [to 5.3.0] versions treated arrays as the string Array, thus returning a string length of 5 and emitting an E_NOTICE level error.
Use
$a = array('tex','ben');
$lengths = array_map('strlen',$a);
to get an array of individual lengths, or
$a = array('tex','ben');
$totalLength = array_sum(array_map('strlen',$a));
to get the total of all lengths
The array is implicitly converted to a string. In PHP this yields the output Array, which has 5 letters as strlen() told you.
You can easily verify this, by running this code:
$a = array('tex','ben');
echo $a;

Php, in_array, 0 value

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);

How does the equivalence operator work with arrays in PHP?

Code:
$arr = array( 10, 20, 30 );
$arr1 = array(
1=>30,
2=>20,
0=>10
);
var_dump( $arr == $arr1 );
$a = array( 1, 2, 3);
$b = array(
1=>2,
2=>3,
0=>1
);
var_dump($a == $b);
This outputs:
bool(false)
bool(true)
Two arrays will be considered equal if their corresponding values are the same.
In your first example you are comparing two arrays:
[10, 20, 30]
[10, 30, 20]
Obviously these are not the same, so it returns false. The second example though:
[1, 2, 3]
[1, 2, 3]
...are the same. Am I missing something here?
If you want to test if two arrays have the same members, see this question:
Algorithm to tell if two arrays have identical members
If you just want to see they have the same totals, you can use array_sum
If you do not specify keys for array, php automatically selects numbers, starting with 0.
Therefore, the following pairs of lines mean the same:
$arr = array(10,20,30);
$arr = array(0=>10,1=>20,2=>30);
$a = array(1,2,3);
$a = array(0=>1,1=>2,2=>3);
It's to be expected, that
array(10,20,30) != array(10,30,20)
and
array(1,2,3) == array(1,2,3)
Given some of your comments, I think it would be useful if you read up on array type in php. Mainly the fact that there is no key-less arrays.
And don't forget comparison operators as well.
Thats a very broad question, but in the case of an array, it compares on an index-by-index basis.
In your first block of code, $arr is not equal to $arr1 because 30 != 10 and 10!=30.
In the second block of code, you are specifying that at index 0, the value is 1. At index 1, the value is 2, and at index 2, the value is 3. Thus, you have the same array.
th equality operator is === in php and within an array => is correct. also $arr !=$arr1 coz 20 !=30, 30!=20 as per you have assigned.

Categories