References in PHP are a means to access the same variable content by different names and they are not actual memory addresses. Instead, they are symbol table aliases. And, when an object is sent by argument, returned or assigned to another variable, the different variables are not aliases: they hold a copy of the identifier, which points to the same object.
On the other hand, I know, an identifier is a name given to an entity (not memory location like references in PHP). Can you explain the differences between 'identifier' and 'references' in PHP in this context?
Let us start with the last part of your quotation.
And, when an object is sent by argument, returned or assigned to another variable, the different variables are not aliases: they hold a copy of the identifier, which points to the same object.
Object Identifiers
In general, an object identifier is an integer value that identifies an object. Let us create some objects from a bare class A
. We would use SPL's spl_object_id()
and var_dump()
functions.
Both functions return the object handle for the given object. The object handle is not a memory address.
class A {}
$a = new A();
$b = $a;
var_dump($a) . PHP_EOL;
var_dump($b) . PHP_EOL;
// object(A)#1 (0) { Notice #1 - an identifier
// }
// object(A)#1 (0) { Notice #1 - an identifier
// }
echo spl_object_id($a) . PHP_EOL; // Outputs: 1 - an identifier
echo spl_object_id($b) . PHP_EOL; // Outputs: 1 - an identifier
$a
and $b
hold a copy of the identifier, which points to the same object (A).
If a PHP script created 500 objects, then each object id would be unique for the lifetime of the object. Each object id can be used as a key for storing objects, or for identifying an object, as long as the object is not destroyed/garbage collected. Once the object is destroyed, its id may be reused for other objects.
Now, let us start with the first part of your quotation.
References in PHP are a means to access the same variable content by different names and they are not actual memory addresses. Instead, they are symbol table aliases.
Reference
In PHP, reference has a different meaning. Therefore, it allows you to access a value with different variable names. A reference is created by the & operator in PHP:
$a = 12;
// Notice the & (ampersand)
$b = & $a; // $b = 12;
$b = 20; // $a = 20; now
Here we can access the value 20
using $a
and $b
. Ok! We now need to know what happens when we assign a value to a variable because you quoted that the different variable names are not actually memory address. Let us dig into that.
zval Container
A PHP variable is stored in a container called a zval. A zval container is created when a new variable is created with a constant value, such as:
$a = "hello";
A zval container stores four types of information about a variable:
There is a function named xdebug_debug_zval()
which is available when Xdebug
is installed; It helps you dig into how a variable with a value resides in a zval container.
$a = "hello";
xdebug_debug_zval('a');
This outputs as the following:
a: (refcount=1, is_ref=0)='hello'
Or graphically you can imagine the zval container as the following:
Symbol Table
The zval container does not include variable names. Those are stored in what is called a symbol table. In the symbol table our "Reference" section's exmaple looks like:
symbol | value
-------+------
a, b | 20
So a
and b
symbols are aliases here. This happens for the scalar types only.
There are four types of scope in PHP - local, global, static, and function parameters. There is a symbol table for each level of scope. As opposed to scalar values, arrays and objects store their properties in a symbol table of their own. In the symbol table, our "Object Identifiers" section's example looks like:
$a = new A();
$b = $a;
symbol | value object | details
-------+--------- -------------+--------
a | object(A)#1 object(A)#1 | class A { ... }
b | object(A)#1
Here a
and b
symbols are not aliases. They hold a copy of the identifier, which points to the same object.
References: