Reference variable in PHP

In this article, I will talk about how object and variable references are controlled in memory, since this is an issue that can generate discussion and differing opinions. One question to ponder is: “By default, are objects passed by reference or by copy in PHP?” I’m going to talk first about what references aren’t in PHP; second, I’ll discuss what they are, and finally, I will examine how the garbage collector works in PHP.

By

Agustin Villalba

Augustin is a Zend-certified full-stack PHP engineer with 10+ years of experience at the likes of FIFA and the European Molecular Bio Lab.

SHARE

SHARE

I first drafted this article while studying for my PHP certification in an effort to better understand how PHP manages variables and objects in memory. After a lot of research, I realized that it was not easy to find answers to my questions, so once I had finished, I decided to document the information so that people can find it all in one place.

In this article, I will talk about how object and variable references are controlled in memory, since this is an issue that can generate discussion and differing opinions. One question to ponder is: “By default, are objects passed by reference or by copy in PHP?” I’m going to talk first about what references are not in PHP; secondly, I’ll discuss what they are, and finally, I will examine how the garbage collector works in PHP.

How does PHP create objects in memory when performing a statement like $a = new Foo();? Nowadays, memory is not as expensive and limited a resource as it was in the past. However, it is still important for good PHP developers to know and understand how variables and objects are managed internally during the execution of their application.

Objects and references in PHP memory and PHP garbage collection

Objects and References in PHP

Many people say—in PHP books and online—that objects in PHP are passed by reference by default. Others say that objects in PHP are allocated by copy. To figure out which statement is correct, first we have to analyze what is (and what is not) a reference in PHP.

What Aren’t References in PHP?

More important than knowing what references are in PHP is knowing what they are not. In PHP, references are not C-style pointers; you cannot do arithmetic operations with references as you can with C pointers. Why? Because, unlike in C, PHP references are not really memory addresses, since they are not numbers indicating a memory location. But then, what are references?

What Are References in PHP?

In PHP, references are “aliases” that allow two different variables to read and write a single value. Put another way, they are mechanisms that allow access to the same value from variables with different names so that they behave as if they are the same variable. Keep in mind that in PHP, variable names and the content of variables are two entirely different things, linked in what it is called the “symbols table.” So, when we create a reference, it simply adds an alias for that variable in the symbol table. Suppose we have the following code:

$a = new Foo();

When the above statement is executed, the variable $a is created in memory, an object of type Foo is created in memory, and an entry is added to the symbol table which indicates that the variable $a “references” (or is related to, or points to, or whatever you want to call it) the Foo object, but it is not a pointer to that object, per se. Conceptually, we have something like this illustration:

Object references in PHP memory

Pop quiz: What happens if we execute this?

$b = $a;

It is not that

$b = $a;
2 becomes a reference of $a; neither can we say that
$b = $a;
2 is a copy of $a. What really happened is that we have created a new variable
$b = $a;
2 in memory and then added a new entry in the symbols table indicating that the variable
$b = $a;
2 also references the same Foo object that $a does. So, visually, we have something similar to what it is shown in this illustration:

Object references in PHP memory

Now, if we execute:

$c = &$a;

We will have created a third variable

$c = &$a;
0 in memory, but not a new entry in the symbols table for
$c = &$a;
0. Instead, in the symbols table, it is recorded that
$c = &$a;
0 is an alias for $a, so it will behave identically, but
$c = &$a;
0 is not a pointer to $a—unlike in C, which creates something called pointers to pointers. To visualize, we have something similar to what it is shown in this illustration:

Diagram of variables and their aliases

As soon as we want to modify the value of any of these three variables (i.e., write a new value), PHP will have to create a new

$c = &$a;
6 structure in memory to separate the content of the variable
$b = $a;
2 and the pair $a/
$c = &$a;
0 so they can each be modified independently without affecting the other’s value. So, if we add the following line to the previous script:

$b = new Bar();

In memory, we will have a situation as represented in the following illustration:

Graphic representation of the situation described above

Now, let’s consider a more complete example:

<?php

class myClass {
    public $var;
		
    function __construct() {
	$this->var = 1;
    }

    function inc() { return ++$this->var; }
}

$a = new myClass(); // $a "references" a Foo object
$b = $a; //b also references the same Foo object as a
//($a) == ($b) == <id> of Foo object, but a and b are different entries in symbols table

echo "$a = ";var_dump($a);
echo "$b = ";var_dump($b);

$c = &$a; //$c is an alias of $a
//($a, $c) == <id> of Foo object, c is an alias of a in the symbols table
echo "$c = ";var_dump($c);

$a = NULL;
//The entry in the symbols table which links "$a" with Foo object is removed
//Since that entry was removed, $c is not related to Foo anymore
//Anyway, Foo still exists in memory and it is still linked by $b
echo "$a = ";var_dump($a);
echo "$b = ";var_dump($b);
echo "$c = ";var_dump($c);
echo "$b->var: ".$b->inc();
echo "$b->var: ".$b->inc();

$b = NULL;
//The entry in the symbols table which links "$b" with the Foo object is removed
//There are no more entries in the symbols table linked to Foo,
//So, Foo is not referenced anymore and can be deleted by the garbage collector

echo "$b = ";var_dump($b);

The output produced by the implementation of the script above is:

$a = object(myClass)#1 (1) { ["var"]=> int(1) } 
$b = object(myClass)#1 (1) { ["var"]=> int(1) } 

$c = object(myClass)#1 (1) { ["var"]=> int(1) } 
$a = NULL 
$b = object(myClass)#1 (1) { ["var"]=> int(1) } 
$c = NULL 
$b->var: 2
$b->var: 3

$b = NULL

PHP Garbage Collection

Finally, let’s see how PHP garbage collection works, since it was introduced in version 5.3. An object or variable in PHP memory will be removed by the PHP garbage collector when there are no references to that object in the symbols table. That is, PHP maintains a references counter of an object from the time it is created so that during the execution of the script PHP, the counter increments and decrements that reference counter based on the variables that are “pointing” to it. Once the reference count reaches 0 (i.e., nothing is referencing that object and, therefore, it is not being used), PHP marks that object as removable, so that in the next pass of the PHP garbage collector, it will be removed from memory, freeing that space for reuse. If you’d like more in-depth detail about how PHP garbage collection works, read this documentation.

Closing Thoughts

I hope I have clarified a little how PHP handles objects and variables in memory and how it “selects” the objects that should be removed by the PHP garbage collector.

Now that you understand how PHP manages variables and objects in memory internally, grab your laptop and start to experiment with some code to prove what you’ve learned. Try playing around with variables and references. Also, experiment with how changing the value of a variable could affect the value of another referencing it. Here’s a question for you: What will be the values of $a and

$b = $a;
2 after the code below is executed?

$a = '1';
$b = &$a;
$b = "2$b";

If you’re interested in reading more about PHP performance features, check out this post by fellow Toptaler Vilson Duka.

Understanding the basics

What are references in PHP?

In PHP, references are “aliases” that allow two different variables to read and write a single value.

How does PHP garbage collection work?

PHP maintains a count of references towards an object from the time it is created. When there are no references to that object in the symbols table, the PHP garbage collector removes it.

How are PHP memory references stored?

PHP memory references are stored in a key-value store called the symbols table.

Tags

PHPGarbageCollectionMemoryReferences

Freelancer? Find your next job.

PHP Developer Jobs

View full profile

Agustin Villalba

Freelance PHP Developer

About the author

Agustin is a web developer with twelve years of experience developing full-stack web applications. He spearheaded the development of a web project for the FIFA Refereeing Department and developed for the European Molecular Biology Laboratory (www.embl.de). He's also a Zend PHP 5.3 Certified Engineer.

Hire Agustin

Comments

Usama Ahmed

It took me less than 3 secs to find out how php manages objects. PHP official manual has a lot of material on it. Does toptal force you to construct articles from a google search?

Usama Ahmed

It took me less than 3 secs to find out how php manages objects. PHP official manual has a lot of material on it. Does toptal force you to construct articles from a google search?

Zbynek

pointer and reference in c is not same, int a = 1; int& b = a; there b is reference, int* c = &a; here it is pointer. in php there are no pointers, but there are references like in c, and they behave mostly like in c, so you should not compare c pointers vs php reference, it doesnt have sence.

Zbynek

pointer and reference in c is not same, int a = 1; int& b = a; there b is reference, int* c = &a; here it is pointer. in php there are no pointers, but there are references like in c, and they behave mostly like in c, so you should not compare c pointers vs php reference, it doesnt have sence.

Agustin

Hi Zbynek, Thank you for comment. Exactly, pointers and references are not the same, that is what we state in the post. Also, as you mentioned, we explain that unlike C pointers, PHP references are not memory addresses, so the comparison is used to remark that they are not the same ;)

Agustin

Hi Zbynek, Thank you for comment. Exactly, pointers and references are not the same, that is what we state in the post. Also, as you mentioned, we explain that unlike C pointers, PHP references are not memory addresses, so the comparison is used to remark that they are not the same ;)

Zbynek

are you thinking then there is someone who think php reference is C pointer? i dont think so.

Zbynek

are you thinking then there is someone who think php reference is C pointer? i dont think so.

Agustin

I honestly doubt you can find detailed and well explained information about PHP internals in 3 seconds. Although PHP documentation is usually good, it does not mean everybody has your "expertise" to understand it. This post was done based on research and own material, so if you do not like it that's great (of course!), but your comment does not add any discussion or debate about the topic, so there is not much to reply! ;)

Agustin

I honestly doubt you can find detailed and well explained information about PHP internals in 3 seconds. Although PHP documentation is usually good, it does not mean everybody has your "expertise" to understand it. This post was done based on research and own material, so if you do not like it that's great (of course!), but your comment does not add any discussion or debate about the topic, so there is not much to reply! ;)

Lars Moelleken

Heyho, here a little bit more constructive comment ;-) If you run the following php-script you can simply see how references und copy-on-write is working: start: 88 bytes array: 8524592 bytes function1-begin: 8524608 bytes function1-end: 17049016 bytes array-test4: 8524536 bytes function2-begin: 8524552 bytes function2-end: 8524616 bytes array-test4_ref: 8524552 bytes end: 8524552 bytes https://github.com/voku/php_zval_test/blob/master/test4.php

Lars Moelleken

Heyho, here a little bit more constructive comment ;-) If you run the following php-script you can simply see how references und copy-on-write is working: start: 88 bytes array: 8524592 bytes function1-begin: 8524608 bytes function1-end: 17049016 bytes array-test4: 8524536 bytes function2-begin: 8524552 bytes function2-end: 8524616 bytes array-test4_ref: 8524552 bytes end: 8524552 bytes https://github.com/voku/php_zval_test/blob/master/test4.php

Mladen Janjetovic

This is not true at all, I have tried to find something well explained like this and it took me a while

Mladen Janjetovic

This is not true at all, I have tried to find something well explained like this and it took me a while

Neda Abbasi

How memory assign to variables in php? Becase php variables has not data type?

Neda Abbasi

How memory assign to variables in php? Becase php variables has not data type?

OAH

donot be such a hater. Write something of this scale and grade then "show-off". Thank you guys in toptal for this great article. Keep up the good work Agustin.

OAH

Now that is some serious stuff down here. Combining this with the fantastic post from stackoverflow on php arrays "copy on write" makes memory mgmt in php so much easier to grasp. Thx guys.

How to declare reference variable in PHP?

In PHP, variable name and variable content are different, so the same content can have different names. A reference variable is created by prefixing & sign to original variable. Hence b=&a will mean that bisareferewncevariableofa.

What is a reference to a variable?

Reference Variables. A reference variable is a variable that points to an object of a given class, letting you access the value of an object. An object is a compound data structure that holds values that you can manipulate. A reference variable does not store its own values.

What is $$ 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.

How to pass PHP variables by reference?

For passing variables by reference, it is necessary to add the ampersand ( & ) symbol before the argument of the variable. An example of such a function will look as follows: function( &$x ). The scope of the global and function variables becomes global. The reason is that they are defined by the same reference.