$c1 = $v1 = array();
$v1['key'] = 'value';
echo '$c1 === $v1: ' . (($c1 === $v1) ? 'true' : 'false'); // prints false
$c1 === $v1 is false. But why? It seems that $v1 is automatically set to a different array then it's origin array automatically. Why it is happening?
Initially $c and $v1 is set to the same array instance. So if I mutate $v1 should not $c reflects the changes as they are set to the same array instance.
These will not be the same, because you explicitly set them to hold different values. The first is empty, while the second holds values.
They are not set to the same reference though, so they are two different variables - when you do
$c1 = $v1 = array();
You create two different arrays. If you want the change of one to reflect in both arrays, you need to make it a reference, by using the & operator in front of the variable identifier, like so.
$v1 = array();
$c1 = &$v1; // $c1 is now a reference to $v1
$v1['key'] = 'value';
echo '$c1 === $v1: ' . (($c1 === $v1) ? 'true' : 'false'); // true!
Notice that you need to reference it after the variable you wish to refer to has been made.
When using a reference like this, it goes both ways - any change to $v1 would be applied to $c1, and the other way around. So they are different variables, but will always hold the same values.
The comparison in the example above holds true because the arrays are exactly the same - not just by reference, but because they hold the same values and keys. If you compare two non-referenced arrays with the exact same values and exact same, matching keys, you would get a true equality too.
var_dump(array('foo') === array('bar')); // false; same keys, different values
var_dump(array('bar') === array('bar')); // true; same keys, same values
var_dump(array('bar') === array('baz' => 'bar')); // false; different keys, same value
Live demo
Passing variables by reference
Because they are two different object, with two different references, with happening one does not affect the other. Just simple like that.
Those arrays will not be the same because the second array has a value. Please run the following code:
<?php
$a = $b = [];
print_r($a);
print_r($b);
$result = ($a === $b) ? 1 : 0;
// The reasult will be 1 because the arrays are both empty.
print_r($result);
$b[0] = 'Ravi';
print_r($a);
print_r($b);
$result = ($a === $b) ? 1 : 0;
// The result will be 0 because the arrays are different.
print_r($result);
Related
This is the code I used to have to check if $A doesn't match $B
if($A!=$B) {
$set = array();
echo $val= str_replace('\\/', '/', json_encode($set));
//echo print_r($_SERVER);
exit;
}
Now I need the opposite of this condition: ($A need to match one of these $B,$C or $D)
A simple shortcut to seeing if a value matches one of multiple values you can put the values to be compared against ($B, $C, and $D) into an array and then use in_array() to see if the original value ($A) matches any of them.
if (in_array($A, [$B, $C, $D])) {
// ...
}
If you don't want it to match any of $B, $C, or $D just use !:
if (!in_array($A, [$B, $C, $D])) {
// ...
}
You can use array_search
$B = 'B';
$C = 'C';
$D = 'D';
//match B
$A = 'B';
$options = [$B, $C, $D];
if (false !== ($index = array_search($A, $options ))) {
echo "Match: {$index} '{$options[$index]}'";
}
Output
Match: 0 'B'
Sandbox
The nice thing here is you can set the $index and use that to tell which one matched later.
Note you have to use false !== because array search returns the index where the match happened at, so it can happen on the first array element which is index 0. As we know PHP can treat 0 as false (in this case the condition would fail when it should pass). However, when we use the strict type check PHP also compares the type and INT 0 is not BOOL false (which passes the condition).
for reference.
http://php.net/manual/en/function.array-search.php
Another probably the most efficient way is to use isset, and use keys instead of values:
$options = [$B=>1,$C=>1,$D=>1]; //values don't matter
if(!isset($options[$A])){
//....
}
In what ways can one determine whether the value of an array's index is falsey due to an out-of-bounds index in PHP?
For example, one might erroneously conclude that both $a and $b below have at least three items each, since the comparison of the third items in both arrays purport to have identical values at index 2, when in reality there is no index 2 in array $b. Indeed both values are null.
$a = array(1, false, null, 1, 0);
$b = array(true, 0);
echo (int)($a[0] === $b[0]); // 0
echo (int)($a[1] === $b[1]); // 0
echo (int)($a[2] === $b[2]); // 1 null<declared>===null<index-out-of-bounds>
echo (int)($a[3] === $b[3]); // 0
echo (int)($a[4] === $b[4]); // 0
Interesting question... Maybe somthing like this (but only for numeric array indexes):
(int)(count($a)>=$i && count($b)>=$i && $a[$i]===$b[$i])
?
EDIT: probably better solution based on array_key_exists:
(int)(array_key_exists($i, $a) && array_key_exists($i, $b) && $a[$i]===$b[$i] )
I have some issues with variables in php that i don't understand.
This is a simplified code example of the issue.
//Create an initial array with an sub-array
$a = array();
$a['test'] = array(1,2);
//Create an reference to $a['test'] in $b
//Changing $b[0] should now change the value in $a['test'][0]
$b = &$a['test'];
$b[0] = 3;
//Create an copy of $a into $c
$c = $a;
//Change one value in $c, which is an copy of $a.
//This should NOT change the original value of $a as it is a copy.
$c['test'][1] = 5;
print_r($a);
print_r($b);
print_r($c);
This is the output:
Array
(
[test] => Array
(
[0] => 3
[1] => 5
)
)
Array
(
[0] => 3
[1] => 5
)
Array
(
[test] => Array
(
[0] => 3
[1] => 5
)
)
The script creates an array with an sub-array and puts two values in it.
A reference to the sub-array is then put into b and one of the values in a is changed in this way.
I then make a copy of a into c.
I then change one value of c.
As c is a copy of a i would expect that the change on c did not affect a. But the output tells a different tale.
Can anyone explain why changing a value in the variable $c affect the value in $a when $c is just a copy of $a? Why is there a 5 in the values of $a?
You're assigning $b to $a by reference (that's what the & prefix does). Any changes to $b will effectively modify $a. Just force a declaration assignment:
$b = $a['test'];
$c does not modify $a. Here's the order of what's going on, and why the arrays are identical:
$a['test'] is assigned an array of 1,2.
$b is assigned as a reference to $a['test'], and modifies its values
$c is then assigned to $a, which has now been modified by $b.
I think i found the answer to my own question... On this page: http://www.php.net/manual/en/language.references.whatdo.php
I can't really understand why it does what it does. I do understand that i should probably avoid mixing references and arrays in the future.
Im refering to this section:
Note, however, that references inside arrays are potentially
dangerous. Doing a normal (not by reference) assignment with a
reference on the right side does not turn the left side into a
reference, but references inside arrays are preserved in these normal
assignments. This also applies to function calls where the array is
passed by value. Example:
<?php
/* Assignment of scalar variables */
$a = 1;
$b =& $a;
$c = $b;
$c = 7; //$c is not a reference; no change to $a or $b
/* Assignment of array variables */
$arr = array(1);
$a =& $arr[0]; //$a and $arr[0] are in the same reference set
$arr2 = $arr; //not an assignment-by-reference!
$arr2[0]++;
/* $a == 2, $arr == array(2) */
/* The contents of $arr are changed even though it's not a reference! */
?>
In other words, the reference behavior of arrays is defined in an
element-by-element basis; the reference behavior of individual
elements is dissociated from the reference status of the array
container.
You are passing the reference $a to $b by using $b = &$a['test']; Hence
change
$b = &$a['test'];
to
$b = $a['test'];
I wondered if there is any way to check if any of a large amount of variables are equal.
If I only have a few variables I can just do this:
if ($a == $b || $a == $c || $b == $c)
However, if I have 20 variables it will take some time to write all combinations. Is there another method?
if (count(array_unique(array($a, $b, $c), SORT_REGULAR)) === 1) {
// all equal
}
All this code does is place the variables in an array and eliminates duplicates. If they are all equal the result of array_unique() should be an array with one value.
If you want to make sure all of them are different it's not much different. Just check to see if the filtered array is the same size as the original array:
$array = array($a, $b, $c);
if (count(array_unique($array, SORT_REGULAR)) === count($array)) {
// all not equal
}
I wish to determine whether there are any duplicates in two arrays, i.e. duplicates in array1 or duplicates in array2. If there are, then set a variable to equal 1, otherwise 0. I have the following code but it does not seem to work and I cannot understand why:
$a = count(array_unique($myarraydf));
$b = count($myarraydf);
$c = count(array_unique($myarrayds));
$d = count($myarrayds);
if (($a == $b) || ($c == $d)) {
$ties = 0;
}
else {
$ties = 1;
}
where $myarraydf and $myarrayds are arrays of numeric values.
If you want to set $ties = 1 if there are duplicates in either set, you need to change your operator to AND:
if (($a == $b) and ($c == $d)) {
If you want to set $ties = 1 if both contain duplicates, then the OR is correct.
I suggest using array_diff, see: http://us3.php.net/array_diff