119

What does the =& (equals-ampersand) assignment operator do in PHP?

Is it deprecated?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kyle J. Dye
  • 1,674
  • 2
  • 10
  • 12

5 Answers5

148

It's not deprecated and is unlikely to be. It's the standard way to, for example, make part of one array or object mirror changes made to another, instead of copying the existing data.

It's called assignment by reference, which, to quote the manual, "means that both variables end up pointing at the same data, and nothing is copied anywhere".

The only thing that is deprecated with =& is "assigning the result of new by reference" in PHP 5, which might be the source of any confusion. new is automatically assigned by reference, so & is redundant/deprecated in$o = &new C;, but not in $o = &$c;.


Since it's hard to search, note that =& (equals ampersand) is the same as = & (equals space ampersand) and is often written such that it runs into the other variable like $x = &$y['z']; or $x = &$someVar (ampersand dollar sign variable name). Example simplified from the docs:

$a = 3;
$b = &$a;
$a = 4;
print "$b"; // prints 4

Here's a handy link to a detailed section on Assign By Reference in the PHP manual. That page is part of a series on references - it's worth taking a minute to read the whole series.

user56reinstatemonica8
  • 32,576
  • 21
  • 101
  • 125
26

It's two different operators. = is assignment as you probably know. And & means the variable should be accessed by reference rather than by value.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Asaph
  • 159,146
  • 25
  • 197
  • 199
  • 64
    I'm sorry but this is way too simplistic. $a =& $b means to make the variable $a refer to the same thing that $b does right now. After this, $a = 5; will also result in $b having a 5. However the reference link may be broken by $b =& $xyz; or unset($b); At which time $a will be the only variable that knows where the cell is that holds the 5. Also beware that if you set $a using =&, you must use =& next time (or unset($a)) to change the reference link of $a, specifically $a = NULL; will not break the link, it only replaces the 5 with null; – Don Apr 07 '10 at 01:51
  • 8
    @Don: Thanks for the elaboration. I can tell you're a C programmer. – Asaph Apr 07 '10 at 03:26
  • 9
    I second what Don says. But I wouldn't say this is way too simplistic. I'd say this is wrong. – Artefacto Aug 21 '10 at 17:11
  • @Don you really should post your comment as an answer. – Adam Jan 04 '19 at 13:42
  • I agree with Artefacto, this answer is wrong and actively misleading. There is no such thing in PHP as "accessing a variable by reference", and assignment by reference *is not* the same operation as a normal assignment. I realise it was a long time ago that you wrote this answer, but can see that you're still active, so please can you have a look at this answer with more experienced eyes, and consider editing or deleting it if you agree that it is incorrect. – IMSoP Apr 08 '21 at 09:06
7
$x = &$y['z'];

also has the effect of creating $y['z'] if it doesn't exist, and setting it to null.

This prevents error messages that you might have wanted to read. I haven't found documentation on this yet; possibly new in 5.3, for all I know.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
malcanso
  • 100
  • 2
  • 7
  • For what it's worth, this behaviour existed at least as far back as PHP 4.3 https://3v4l.org/3g2WZ It's sometimes called "autovivification", but I don't know where in the manual it's described in detail. – IMSoP Jun 28 '22 at 09:35
6

The symbol & is used in various ways in PHP to represent operations with "references". The PHP manual has a section titled References Explained which every PHP programmer should read.

It's important to understand that references in PHP are not a data type, like a pointer, but a concept regarding how variables work. There is therefore no single meaning of & - you should not read it as "make a reference" - it just means "something reference-y is happening here".

In particular, the syntax $a =& $b, which can also be written $a = &$b, represents assignment by reference. It binds two variables together, so that they both point at the same piece of data. Think of the & as modifying the = rather than modifying the $b.

Once you've bound two variables together in this way, they are interchangeable - you can't say that "$a points to $b" or "$b points to $a":

$a =& $b;
$a = 42;
// both $a and $b will be 42
$b = 101;
// both $a and $b will be 101

You can also link more than two variables together as references, and again it doesn't matter which of the existing names you use on the right-hand side of the assignment:

$a =& $b;
$c =& $b;
$d =& $a;
$e =& $c;
// $a, $b, $c, $d, and $e now all point to the same data, interchangeably

However, if you put the same variable on the left-hand side, it breaks the existing link of that variable, and links it to something else:

$a =& $b;
// $a and $b are linked together

$a =& $c;
// $a is now linked to $c
// the value of $b doesn't change, but it is not linked to $a or $c

To "break" the link without making a new link, you can use the unset keyword:

$a =& $b;
$c =& $a;
// $a, $b, and $c are all linked together
unset($a);
// $b and $c are still linked together, but $a is independent

Some descriptions refer to =& as "creating or adding to a reference set". Perhaps it would have been better if it had been implemented as a function, like bind($a, $b) to highlight that both arguments are affected by the operation.

IMSoP
  • 89,526
  • 13
  • 117
  • 169
1

I'd like to draw some attention to the semantics and code styling of "Assigning By Reference". The OP's opening sentence hints toward a misconception:

What does the =& (equals-ampersand) assignment operator do in PHP?

First, let's review the dedicated section of the PHP Docs page for Assignment Operators. Notice how the = comes before the & and that the two symbols are separated. This is because they are NOT "combined operators". Semantically, it is "assigning" a "reference"; it is not a "reference assignment operator".

Second, look at how ALL of the "combined operators" are written lower on the docs page. The = is consistently the right-most symbol. This is a very important distinction because writing the & on the left of the = changes the meaning -- it becomes a combined operator ("bitwise and assignment operator") instead of an assignment to a reference.

PSR coding standards should be something that all PHP developers are aware of and strive to obey. Notice this rule of PSR-12 Section 6.2:

All binary arithmetic, comparison, assignment, bitwise, logical, string, and type operators MUST be preceded and followed by at least one space

By this rule, there should always be a space after the = operator -- this makes =& a violation.

Furthermore, there are other rules that state that there should not be a space between & and its variable/argument/function/etc.

When using the reference operator & before an argument, there MUST NOT be a space after it


TL;DR

When assigning a reference, always write the = with spaces on both sides and never write a space after &.

  • Bad: $a =& $b;
  • Good: $a = &$b;

Demonstrated consistently/correctly: https://riptutorial.com/php/example/11991/assign-by-reference

Not demonstrated consistently/correctly:

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • @LucidKit I could not leave a comment with my suggested edit rejection. I denied the change of the hyperlink because the original link works and I don't see any benefit in changing it. I am also not interested in bloating my answer with a list of webpage links where the appropriate syntax is drmonstrated -- one is enough to prove my point and I pick this one by random (I have no affiliation with that site). – mickmackusa Nov 19 '20 at 08:03
  • Upon closer inspection, it looks likely that you are the Admin of said website as the linked page was edited mere minutes ago AND the Admin user was created on that site 13 days ago. This makes it look like you are trying to advertise your content via my answer and this REALLY encourages me to deny your edits and keep track of your edits elsewhere in Stack Exchange for more undisclosed affiliation. – mickmackusa Nov 19 '20 at 08:09
  • I think you are reading far too much into coding styles where people probably haven't even considered the question at all. The reality is that in PHP, assignment by reference **is** a specific operation, and the `&` is not available as a general purpose operator. The manual actually has [a section on Assignment by Reference](https://www.php.net/manual/en/language.references.whatdo.php#language.references.whatdo.assign) which does indeed spell it like a single `=&` operator, and [always has done](https://github.com/php/doc-en/commits/master/language/references.xml). – IMSoP Apr 07 '21 at 08:55
  • Just because something _has always been done a certain way_, doesn't mean that it is the right way or the best way. – mickmackusa Apr 07 '21 at 22:38
  • I absolutely agree, and only mentioned what the manual uses because you did; since it uses both forms, it doesn't make sense to use it as evidence either way. I believe `=&` is the best way to write it, regardless of who else uses it, because contrary to what you write here, it is a "reference assignment operator". Although `&` is used in several related ways in PHP, it is not a standalone operator, and `&$foo` on its own does not have any meaning. – IMSoP Apr 08 '21 at 06:46
  • But it is a syntactical outlier -- since it would be the only combined operator with a leading `=`. Even if you don't agree with PSR standards, splitting these operators creates consistency in the code styling. Are there any other "combined operators" that violate the proposed convention of `=`-last? – mickmackusa Apr 08 '21 at 06:48
  • If we were discussing how to design the language, then sure, maybe it should be &= or :& or something. But we're not, we're discussing what makes PHP code clearest to read, and in my opinion, that is treating =& as a single operator. – IMSoP Apr 08 '21 at 06:52
  • Okay, then we will agree to disagree. I don't like that `&=` (a true combined operator) could be easily mistaken for the valid `=&` assignment which has a very different purpose. Unfortunately, I cannot neutralize your dv and I think only posts that are incorrect or do harm should have a negative tally. – mickmackusa Apr 08 '21 at 06:55
  • 3
    Regardless of opinions about whitespace, the premise of this answer is actively misleading: assignment by reference **can not** be analysed as an assignment plus a reference, it is a distinct operation. If you set `$a = &$b` then all assignments to $a also affect $b: `$a = 42; $a = foo(); $a = $c;` etc; if `$a = &$c;` is an assignment, then logically it should _also_ affect $b, *but it doesn't*, it links $a and $c, and breaks the link with $b. That's because it's not an "assignment" operation, it's an "assignment by reference" operation. – IMSoP Apr 08 '21 at 07:59