In regards to references in PHP, these are some issues to be aware of:
PHP uses copy-on-write to handle an assignment, and so
$b = $a
will not write $b to a different variable container until there is a change that brings the two variables to differ. One type of change that can occur is that a reference to $b is made by another variable such as$c = &$b
(in order for it to be a reference, it now has to copy $b). In C++ a reference does not have its own memory address, and is considered an alias that is-the-object-itself (even though in certain circumstances you can still have dangling references). In PHP, references "... are not like C pointers [pointers - not C++ references]; for instance, you cannot perform pointer arithmetic using them, they are not actual memory addresses, and so on." Given the above information, we see that copying a variable does not take extra memory until a change is made. References in PHP, in some circumstances will add to memory. This happens when$b = $a
and$c = &$b
(unlike$c = &$a
), since even though $b has not changed from $a, it needs its own reference tracking mechanism within a separate zval variable container for $b, and therefore triggers a write for $b.Differences between current and legacy versions of PHP can lead to different handling: "In PHP 4 objects are treated like other variables so when using them as function parameters or doing assignments they are copied. In PHP 5 they are always passed by reference."
Languages, human or computer, normally tend toward simplification where possible (unless there is a benefit for complexity that outweighs simplicity):
- It is more difficult to track referenced changes coming out of a function / method (since there is no way, without looking at the function / method, to see which parameters are passing out as referenced).
- It is more difficult to keep track of changes involving underlying references.
- Core functionality sometimes handles differently for references.
- For instance:
$b = &a; unset($b);
does not unset $a, but is used to disassociate $b from $a (in this case $b is unset, $a retains its value). - For instance: array_filter() does not work with passed references.
- This does not work:
$a=array(0,'', -1); $b = &a; print_r(array_filter($b));
- This does not work:
- For instance:
Unexpected Results:
- Code like the following does not work as you would expect:
$array1 = array(1,2);
$x = &$array1[1]; // Unused reference
$array2 = $array1; // reference now also applies to $array2 !
$array2[1]=22; // (changing [0] will not affect $array1)
print_r($array1);
Produces:
Array (
[0] => 1
[1] => 22 // var_dump() will show the & here
)