Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to use the ampersand in PHP 5.5.X and above anymore?

I'm getting mixed signals all over the place.

Do I use the ampersand to pass variables by reference or not?

The following link seems to tell me that it is deprecated and no longer necessary:
http://gtk.php.net/manual/en/html/tutorials/tutorials.changes.references.html

But threads like these make me wonder:
Call-time pass-by-reference deprecated?
PHP and ampersand

Let me phrase my question as an example.

If I make a function, using PHP 5.5.5:

function recurring_mailer_form($form, $form_state) 
{

}

Is it the same as:

function recurring_mailer_form($form, &$form_state) 
{

}

?

like image 807
Nathan Lutterman Avatar asked Nov 07 '13 22:11

Nathan Lutterman


People also ask

What is the use of ampersand in PHP?

An ampersand just before the function name will return a reference to the variable instead of returning its value. Returning by reference is useful when you want to use a function to find to which variable a reference should be bound.

What does & in front of variable mean PHP?

To assign by reference, simply prepend an ampersand (&) to the beginning of the variable which is being assigned (the source variable).

What does a $$$ mean in PHP?

PHP $ and $$ Variables. The $var (single dollar) is a normal variable with the name var that stores any value like string, integer, float, etc. The $$var (double dollar) is a reference variable that stores the value of the $variable inside it.

Can we have two functions with the same name in PHP Why or why not?

Since PHP is a dynamically typed language, this is not possible.


2 Answers

The reason different articles seem to be saying different things is that they are talking about different kinds of pass-by-reference.

The main thing that determines if a parameter should be passed by reference is the function signature itself, and the fundamentals of this have not changed since PHP 4. Consider this example:

function foo( $by_value, &$by_reference ) { /* ... */ }

$a = 1; $b = 2;
foo( $a, $b );

Here, the outer variable $a is being passed to the function by value, as though it is being assigned as $by_value = $a; - changes to $by_value cannot affect $a. The variable $b however is being passed by reference; just like an assignment of the form $by_reference =& $b; this means that there is one variable referenced by two names, and any assignment to one will act as an assignment to both.

If you pass an "ordinary" value (a string, number, or array) by value, its value is just copied to the new variable. As of PHP 5: If you pass an object by value, however, something slightly different happens - the "value" copied is just a pointer to the same object. This means that if $a were an object, you could call $by_value->some_property = 42; and $a->some_property would also be 42. However, if you assigned some new value to $by_value, it would still not affect $a.

Until PHP 5.4, there was an extra way to pass a parameter by reference, which was to "force" the reference behaviour at call-time. This meant that you could write foo(&$a, &$b); and "capture" changes made to $by_value inside the foo() function. Relying on this was generally a bad idea, and so it was removed. (It landed in 5.4 because it was intended for removal in PHP 6, but that project was put on indefinite hold, with the smaller changes landing in 5.3 and 5.4).

Finally, functions can return a variable by reference (as discussed in the manual here). This is a little fiddly, as it actually requires you to put & in two places: at the beginning of the function declaration, to say that return should mean "return this variable reference" not "return this value"; and in the code calling it, to assign a variable to that reference, rather than just copying its value. Here's a silly example which combines a reference parameter with a reference return (the two do not have to go together, it's just an example):

function &bar(&$some_param) { return $some_param; }
$a = 1;
$b =& bar($a);
// $b and $a now point at the same variable, not just the same value
// it was passed into and out of a function, and assigned to a new variable, 
// but all those operations were by reference

Note that many people mistakenly believe that passing a variable by reference will give them a performance benefit, and this was often their only reason for using call-time pass-by-reference. This is in fact usually wrong, as the Zend Engine which powers PHP uses a technique called "copy on write" to leave multiple variables which happen to have the same value pointing at the same piece of memory, even if they are not bound up as references. In fact, reference assignment generally defeats this optimisation, due to the way the engine tracks which variables are in the copy-on-write state.

like image 143
IMSoP Avatar answered Sep 22 '22 14:09

IMSoP


No, it is not.

  • Objects are always automatically passed as references (info! see below for additional important information!)

  • Declaring paramters as references must happen at the function definition:

    function test(&$var) {}
    

    Not at the time of calling it:

    // wrong
    $var = '123';
    test(&$var);
    


If you pass an object as usual, you can alter the object's state (properties).
Assume that $obj is an instance of the class TestClass which contains a member variable called hello (click here for a full sample at Ideone.com):
function modify($obj) { $obj->hello = 'world (modified)!'; }

$obj->hello = 'world';
modify($obj);
var_dump($obj->hello);  // outputs "world (modified!)"

This should be self-explanatory. Now, using the same code but assigning another value to $obj instead modifying the object's state results in no modification (→ Ideone.com):

function modify($obj) { $obj = 42; }
// ...
var_dump($obj->hello);  // outputs "world"

Only accepting the parameter explicitly as a reference gives us the ability to completely change the variable's contents (→ Ideone.com):

function modify(&$obj) { $obj = 42; }
// ...
var_dump($obj);         // outputs "42"
like image 40
ComFreek Avatar answered Sep 19 '22 14:09

ComFreek