PHP's =& operator - php

Are both these PHP statements doing the same thing?:
$o =& $thing;
$o = &$thing;

Yes, they are both the exact same thing. They just take the reference of the object and reference it within the variable $o. Please note, thing should be variables.

They're not the same thing, syntactically speaking. The operator is the atomic =& and this actually matters. For instance you can't use the =& operator in a ternary expression. Neither of the following are valid syntax:
$f = isset($field[0]) ? &$field[0] : &$field;
$f =& isset($field[0]) ? $field[0] : $field;
So instead you would use this:
isset($field[0]) ? $f =& $field[0] : $f =& $field;

They both give an expected T_PAAMAYIM_NEKUDOTAYIM error.
If you meant $o = &$thing; then that assigns the reference of thing to o. Here's an example:
$thing = "foo";
$o = &$thing;
echo $o; // echos foo
$thing = "bar";
echo $o; // echos bar

The difference is very important:
<?php
$a = "exists";
$b = $a;
$c =& $a;
echo "a=".$a.", b=".$b.", c=".$c."<br/>"; //a=exists b=exists c=exists
$a = null;
echo "a=".$a.", b=".$b.", c=".$c; //a= b=exists c=
?>
Variable $c dies as $a becomes NULL, but variable $b keeps its value.

If you meant thing with a $ before them, then yes, both are assigning by reference. You can learn more about references in PHP here: http://www.php.net/manual/en/language.references.whatdo.php

Yes, they do. $o will become a reference to thing in both cases (I assume that thing is not a constant, but actually something meaningful as a variable).

Related

How to use a pointer in a PHP function? [duplicate]

This question already has answers here:
Are there pointers in php?
(9 answers)
Closed 7 years ago.
In C we can use pointer for a function parameter:
test( *text);
function test( *txt){
//codes goes here
}
Is it possible in PHP?
Variable names in PHP start with $ so $entryId is the name of a variable.
$this is a special variable in Object Oriented programming in PHP, which is reference to current object.
-> is used to access an object member (like properties or methods) in PHP, like the syntax in C++.
So your code means this: place the value of variable $entryId into the entryId field (or property) of this object.
The & operator in PHP, means pass reference. Here is an example:
$b=2;
$a=$b;
$a=3;
print $a;
print $b;
// output is 32
$b=2;
$a=&$b; // note the & operator
$a=3;
print $a;
print $b;
// output is 33
In the above code, because we used & operator, a reference to where $b is pointing is stored in $a. So $a is actually a reference to $b.
There is a good explanation of pointers on this page
There are references, but that's not the same as pointers.
php.net has multiple pages explaining What References Are, What References Do and What References Are Not.
There too, it is mentioned multiple times that
References are not pointers.
They provide a way to assign $a to $b so that if you reassign $b, $a changes as well:
$a = 'a';
$b = &$a; // Reference
$b = 'b'; // Now $a == 'b'
This can be used for function arguments as well:
function myFunc(&$b)
{
$b = 'b';
}
$a = 'a';
myFunc($a); // Now $a == 'b'
Before PHP 5.3.0 is was also possible to do a thing called "call-time pass-by-reference", where you would have a "normal" function declaration and use the & operator in the call instead:
function myFunc($b)
{
$b = 'b';
}
$a = 'a';
myFunc(&$a); // As of PHP 5.3.0 produces a Fatal Error, saying:
// Call-time pass-by-reference has been removed; If you would like to pass argument by reference, modify the declaration of myFunc().
But beware! Assigning another reference will not update the original reference:
$a = 'a';
$b = 'b';
$c = &$a;
$c = &$b; // $a == 'a'
[ Demo ]
A trap resulting from that exists with the global keyword.
$a = 'a';
$b = 'b';
function myFunc()
{
global $a, $b;
$a = &$b;
var_dump($a);
}
myFunc(); // 'b'
var_dump($a); // 'a'
That is because global $a effectively means $a = &$GLOBALS['a'], so assigning it a new reference will not update $GLOBALS.
Of course you can prevent that by using $GLOBALS directly.
But if you're using globals at all, you should probably rethink your design anyway.
With references, there is now also a difference between setting a variable = NULL and using unset().
= NULL follows references, unset() does not:
$a = 'a';
$b = &$a;
unset($b); // $a == 'a'
$a = 'a';
$b = &$a;
$b = NULL; // $a == NULL
[ Demo ]
Bottom line:
References allow for things that wouldn't be possible without them, but sometimes do not behave the way one would expect them to, because of how PHP was built.

Updating a variable inside another variable

I'm wondering if it is possible to update a variable which is inside another variable.
Here is an example:
$t = 15;
$dir ='foo and some more text'.$t.'and more foo';
$t = 10;
print_r($dir);
For me $dir outputs $t as 15 not as 10.
Can anyone help me with this?
You're misunderstanding what that code is actually doing. This line:
$dir ='foo and some more text'.$t.'and more foo';
doesn't store a reference to $t for future evaluation. It evaluates $t to whatever value it has at that time and uses the result to construct the value placed in $dir. Any reference to $t is lost before the engine even gets to the step of assigning it to $dir.
You can pass a variable to a function, you can encapsulate variable state in an object, but an evaluated string doesn't reference a variable.
This is not possible. But you can make something similar with preg_match and a custom print function.
This is an just example how it could be done (warning: experimental):
<?php
$blub = 15;
$test = 'foo and some more text %blub and more foo %%a';
function printv($text) {
$parsedText = preg_replace_callback('~%([%A-Za-z0-9]+)~i', function($matches) {
if ($matches[1][0] != '%') {
return $GLOBALS[$matches[1]];
}
return $matches[1];
}, $text);
echo $parsedText;
}
$blub = 17;
printv($test);
?>
What ever be the value of $t at the time of assigning $dir the value is 15. That will be stored and assigned. This is same for all the languages.
Or if you want to, its easy to do it with anonymous function.
$dir = function ($t) {return 'foo and some more text'.$t.'and more foo';}
echo $dir(10);
//foo and some more text10and more foo
echo $dir(15);
//foo and some more text15and more foo

What is the difference between assigning an object and assigning an object reference?

I read object references in PHP.I did some experimentation with object references.
My doubt is:
I assigned an object to another variable.Then,I changed the value of variable and print the variable.The both variable get affected.I assigned a object reference to another variable.Then I changed value of variable in one,that affect in both.
<?php
##Class
class A
{
var $foo = 1;
}
#Assignment
$a = new A();
$b = $a;
echo "Assignment:\n";
$b->foo = 8;
echo $a->foo."\n";
echo $b->foo."\n";
#Reference
$c = new A();
$d =& $c;
echo "References:\n";
$d->foo = 4;
echo $c->foo."\n";
echo $d->foo."\n";
?>
My question is :
What is the difference between assigning an object and assigning an object reference.
Whether the both are same or is there any difference?
What is the difference between assigning an object and assigning an object reference
PHP does not have object references, so you can not compare against something that does not exist.
However I assume you want to know the difference between:
$a = new Foo;
$b = $a;
and
$a = new Foo;
$b = &$a;
The first one is an assignment of the object (which is an object identifier) and the second is making $b an alias of $a. The difference should become clear if we change the flow a bit:
$a = NULL;
$b = $a;
$a = new Foo;
and
$a = NULL;
$b = &$a;
$a = new Foo;
In the first example (assignment), $b is NULL. In the second example, $b is a variable-alias (a.k.a. PHP variable reference).
After execution, ìn the first example $b is naturally NULL whereas in the second one it is what $a is.
As you can see, independent to objects, doing an assignment is just not the same as creating a variable reference.
I hope this clarifies this a bit for you. Don't talk about references, just talk about variable aliasing. That better matches it in the PHP world.
This is explained in detail in the manual, but I'll explain it again:
When PHP creates an object, it assigns the variable an object identifier, which allows access to that object. When you pass an object as an argument, or assign it to a variable, you actually give the variable a copy of that identifier.
For almost all testcases and situations, they are both the same.

Best way to give a variable a default value (simulate Perl ||, ||= )

I love doing this sort of thing in Perl: $foo = $bar || $baz to assign $baz to $foo if $bar is empty or undefined. You also have $foo ||= $bletch which will only assign $bletch to $foo if $foo is not defined or empty.
The ternary operator in this situation is tedious and tiresome. Surely there's a simple, elegant method available in PHP?
Or is the only answer a custom function that uses isset()?
PHP 5.3 has a shorthand ?: operator:
$foo = $bar ?: $baz;
Which assigns $bar if it's not an empty value (I don't know how this would be different in PHP from Perl), otherwise $baz, and is the same as this in Perl and older versions of PHP:
$foo = $bar ? $bar : $baz;
But PHP does not have a compound assignment operator for this (that is, no equivalent of Perl's ||=).
Also, PHP will make noise if $bar isn't set unless you turn notices off. There is also a semantic difference between isset() and empty(). The former returns false if the variable doesn't exist, or is set to NULL. The latter returns true if it doesn't exist, or is set to 0, '', false or NULL.
In PHP 7 we finally have a way to do this elegantly. It is called the Null coalescing operator. You can use it like this:
$name = $_GET['name'] ?? 'john doe';
This is equivalent to
$name = isset($_GET['name']) ? $_GET['name']:'john doe';
Thanks for all the great answers!
For anyone else coming here for a possible alternative, here are some functions that help take the tedium out of this sort of thing.
function set_if_defined(&$var, $test){
if (isset($test)){
$var = $test;
return true;
} else {
return false;
}
}
function set_unless_defined(&$var, $default_var){
if (! isset($var)){
$var = $default_var;
return true;
} else {
return false;
}
}
function select_defined(){
$l = func_num_args();
$a = func_get_args();
for ($i=0; $i<$l; $i++){
if ($a[$i]) return $a[$i];
}
}
Examples:
// $foo ||= $bar;
set_unless_defined($foo, $bar);
//$foo = $baz || $bletch
$foo = select_defined($baz, $bletch);
I'm sure these can be improved upon.
A common idiom to stay compatible with older PHP versions is:
$var = $bool or $var = "default";
// If I use it, then only with excessive spaces for clarity.
This works for values that can be evaluated in boolean context. The advantage here is that it also gives you said debug e_notice should the variable be undefined.
In PHP earlier than 7.*, one may use ?: for an undefined variable having errors locally suppressed with an #:
$foo = #$bar ?: $baz;
this is another good format for the isset case
isset($foo) || $foo= $bar;
another simple way and will give you more control as you can add more conditions and assign to another variable in the same time
$foo = (isset($oData['foo']))?$bar['foo']:'default value';
A possible solution: defaultFor( )
Unless we have a factory solution (which is indeed very annoying), I'd recommend the following little helper. It does the job in most cases:
function defaultFor(&$x,$default=null) {
if(!isset($x)) $x = $default;
}
//-------------------- Now you can do this: --------------
defaultFor($a,"Jack"); // if $a is not set, it will be "Jack"
defaultFor($x); // no more notices for $x but keep it !isset
I hope this is close to what you wanted to achieve. It will not give you any notices if you use it with a nonexistent variable, and it's quite convenient. Surely it has a drawback: the default value always gets calculated beforehand so don't use it with anything heavy as a second parameter, like a file_get_contents or something. In those cases, you're better off with isseting.
I think in general doing something like this:
$foo = $bar || $baz;
is a bad idea, unless $bar and $baz are both booleans. If they aren't:
$bar = 10;
$baz = 11;
then the question becomes: what determines if something is true or false? Most people would probably expect zero to be false, and everything else to be true. But with some languages (for example Ruby), only false and nil are false, which means both 0 and 1 would be true. Because of this cross language ambiguity, I think it best to be explicit in these cases:
if ($bar !== 0) {
$foo = $bar;
} else {
$foo = $baz;
}
or:
$foo = $bar !== 0 ? $bar : $baz;

What does the PHP operator =& mean? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What do the "=&" and "&=" operators in PHP mean?
I found the operator "=&" in the following code, and I do not know what it means. What does it mean and what does it do?
The code where I read it:
function ContentParseRoute($segments)
{
$vars = array();
//Get the active menu item
$menu =& JSite::getMenu();
$item =& $menu->getActive();
// Count route segments
$count = count($segments);
....
This isn't an assignment (=) by reference (&).
If you were to say:
$a = 42;
$b =& $a;
You are actually saying assign $a by reference to $b.
What assigning by reference does is "tie" the two variables together. Now, if you were to modify $a later on, $b would change with it.
For example:
$a = 42;
$b =& $a;
//later
echo $a; // 42
echo $b; // 42
$a = 13;
echo $a; // 13
echo $b; // 13
EDIT:
As Artefacto points out in the comments, $a =& $b is not the same as $a = (&$b).
This is because while the & operator means make a reference out of something, the = operator does assign-by-value, so the expression $a = (&$b) means make a temporary reference to $b, then assign the value of that temporary to $a, which is not assign-by-reference.
It is the referential assignment operator.
This means that when you modify the LHS of the operator later on in code, it will modify the RHS. You are pointing the LHS to the same block of memory that the RHS occupies.
Here's an example of it in use:
$array = array('apple', 'orange', 'banana');
// Without &
foreach($array as $d)
{
$d = 'fruit';
}
echo implode(', ', $array); // apple, orange, banana
// With &
foreach($array as &$d)
{
$d = 'fruit';
}
echo implode(', ', $array); // fruit, fruit, fruit
Not an explanation, but an example of being able to use the & operator without using it in an =& assignment.

Categories