Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h1>=&amp;</h1> <p><code>$a =&amp; $b</code> turns <code>$a</code> into an alias for <code>$b</code>. If the value or reference of <code>$a</code> is changed, the value or reference of <code>$b</code> will change accordingly.</p> <p>This differs from "both pointing to the same place" when it comes to objects: I could do <code>$c = $d = new AnObject(</code>), and both variables would point to the same place; however, changing where one points would not change where the other points. That is, <code>$c = null</code> would not make <code>$d = null</code>. In the case of <code>$a =&amp; $b</code>, however, <code>$a = null</code> would make <code>$b = null</code>.</p> <p><em>Note: Officially, aliases are actually called references. The official terminology is a bit of a misnomer and is certainly ambiguous, so I've opted to use the term "alias" instead. For documentation, see <a href="http://php.net/manual/en/language.references.php" rel="noreferrer">php.net</a>.</em></p> <h2>Uses and effects</h2> <p>With scalar values, <code>=&amp;</code> is sort of like wrapping the value in an object, so that you can change the value universally among several variables. With types that are normally passed by reference (objects), <code>=&amp;</code> provides a reference to a reference.</p> <p>I tend to use <code>=&amp;</code> when I'm working with associative arrays. Rather than rewriting <code>$foo['bar']['foobar']</code> several times over, I can create an alias: <code>$foobar =&amp; $foo['bar']['foobar']</code>. These even works if the index doesn't exist yet. If <code>$foo['bar']['foobar']</code> doesn't exist, then <code>isset($foobar)</code> will be false. It's better than using a plain old variable, because I can create the alias before testing for the existence of the key without triggering an error.</p> <p>Just be sure to unset (<code>unset($foobar)</code>) the alias when you're done. Otherwise, if you reuse the variable name later, you'll end up overwriting whatever the alias was pointing to.</p> <p>You can use aliases in other ways, too--they're not limited to assignments. They work with:</p> <ul> <li>foreach loops: <code>foreach ($a as &amp;$b)</code> Assigning to <code>$b</code> will overwrite the corresponding value in <code>$a</code>. Unset <code>$b</code> when you're done, or you'll run into weird problems!</li> <li>function/method parameters: <code>function foobar(&amp;$a)</code> Assigning to <code>$a</code> within <code>foobar</code> will change whatever variable the caller passed as <code>$a</code>.</li> <li>function/method return values: <code>function &amp;foobar()</code> Whatever is returned can be modified by the caller; this is useful for passing around aliases. It's also easy to abuse.</li> <li>arrays: <code>$a = array(&amp;$b)</code> Any changes to <code>$a[0]</code> will now affect <code>$b</code>, including assignments.</li> <li>call_user_func_array: <code>call_user_func('foobar', array(&amp;$a))</code> Assuming <code>foobar</code> takes a single alias parameter, <code>foobar</code> can now modify <code>$a</code>. This allows you to call functions/methods with alias parameters using <code>call_user_func_array</code>.</li> </ul> <h2>Examples</h2> <h3>Scalars</h3> <pre><code>$original = 1; $copy = $original; $reference =&amp; $original; // All three variables == 1. $reference = 2; // $original == 2, $reference == 2, $copy == 1 $original = 3; // $original == 3, $reference == 3, $copy == 1 $copy = 4; // $original == 3, $reference == 3, $copy == 4 </code></pre> <h3>Objects</h3> <pre><code>#!/usr/bin/env php &lt;?php class Object { private $properties; public function __construct(array $properties = array()) { $this-&gt;properties = $properties; } public function __isset($key) { return isset($this-&gt;properties[$key]); } public function __unset($key) { unset($this-&gt;properties[$key]); } public function __get($key) { return isset($this-&gt;$key) ? $this-&gt;properties[$key] : null; } public function __set($key, $value) { $this-&gt;properties[$key] = $value; } public function __toString() { return print_r($this-&gt;properties, true); } } function print_vars() { global $original, $ref, $refref; echo '$original: ', $original, '$ref: ', $ref, '$refref: ', $refref, PHP_EOL; } $original = new Object(array('a' =&gt; 1, 'b' =&gt; 2, 'c' =&gt; 3)); $ref = $original; $refref =&amp; $original; print_vars(); /* $original: Array ( [a] =&gt; 1 [b] =&gt; 2 [c] =&gt; 3 ) $ref: Array ( [a] =&gt; 1 [b] =&gt; 2 [c] =&gt; 3 ) $refref: Array ( [a] =&gt; 1 [b] =&gt; 2 [c] =&gt; 3 ) */ $original-&gt;a = 'duck'; $ref-&gt;b = 'moose'; $refref-&gt;c = 'cow'; print_vars(); /* $original: Array ( [a] =&gt; duck [b] =&gt; moose [c] =&gt; cow ) $ref: Array ( [a] =&gt; duck [b] =&gt; moose [c] =&gt; cow ) $refref: Array ( [a] =&gt; duck [b] =&gt; moose [c] =&gt; cow ) */ // This carries over to $refref, but not $ref. $original = new Object(array('x' =&gt; 1, 'y' =&gt; 2, 'z' =&gt; 3)); print_vars(); /* $original: Array ( [x] =&gt; 1 [y] =&gt; 2 [z] =&gt; 3 ) $ref: Array ( [a] =&gt; duck [b] =&gt; moose [c] =&gt; cow ) $refref: Array ( [x] =&gt; 1 [y] =&gt; 2 [z] =&gt; 3 ) */ // This does *not* carry over to $original or $ref. $ref = new Object(array('o' =&gt; 42, 'm' =&gt; 123, 'n' =&gt; 1337)); print_vars(); /* $original: Array ( [x] =&gt; 1 [y] =&gt; 2 [z] =&gt; 3 ) $ref: Array ( [o] =&gt; 42 [m] =&gt; 123 [n] =&gt; 1337 ) $refref: Array ( [x] =&gt; 1 [y] =&gt; 2 [z] =&gt; 3 ) */ // This *does* carry over to $original, but not $ref. $refref = new Object(array('alpha' =&gt; 10, 'beta' =&gt; 20, 'gamma' =&gt; 30)); print_vars(); /* $original: Array ( [alpha] =&gt; 10 [beta] =&gt; 20 [gamma] =&gt; 30 ) $ref: Array ( [o] =&gt; 42 [m] =&gt; 123 [n] =&gt; 1337 ) $refref: Array ( [alpha] =&gt; 10 [beta] =&gt; 20 [gamma] =&gt; 30 ) */ ?&gt; </code></pre> <h1>&amp;=</h1> <p><code>&amp;=</code> is unrelated to <code>=&amp;</code>. It comes from a set of assignment operations. Here's just a few:</p> <ul> <li><code>+=</code></li> <li><code>-=</code></li> <li><code>*=</code></li> <li><code>/=</code></li> </ul> <p>See the trend here?</p> <p>Binary arithmetic operators generally have assignment counterparts. Let's say <code>@</code> were an arithmetic operator (it's not as of writing) such that <code>$a @ $b</code> generally yields a number when <code>$a</code> and <code>$b</code> are numbers. (Think: Addition, multiplication, division, etc.) How often do you need to do something like this?</p> <pre><code>$a = $a @ $b; </code></pre> <p>Pretty often. Doesn't it seem a bit unnecessary to repeat <code>$a</code>? Many languages, including PHP, solve this with an array of assignment operators:</p> <pre><code>$a @= $b; </code></pre> <p>Much simpler, and to a programmer accustomed to this notation, perhaps more concise and descriptive at a glance. (I certainly find it easier to read, since I'm so used to it.) So to double a variable:</p> <pre><code>$a *= 2; </code></pre> <p>Quick, easy, and relatively descriptive. Some languages, including PHP, extend this feature beyond arithmetic for an extra operation or two. Notably:</p> <pre><code>$a = $a . 'Appended text'; // Is the same as: $a .= 'Appended text'; </code></pre> <p>Very useful.</p> <p><code>&amp;=</code> falls among these assignment operators, because <code>&amp;</code> represents a <a href="http://php.net/manual/en/language.operators.bitwise.php" rel="noreferrer">bitwise arithmetic AND operation</a>. There are a few others listed in the PHP documentation (see aforementioned link), all of which are common to many programming languages.</p> <p>This means that <code>$a &amp;= $b</code> is the same as <code>$a = $a &amp; $b</code>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload