Skip links
Main content

PHP myths confused

Thursday 18 December 2008 17:16

Every now and then, when you least expect it, PHP behaves in an unexpected way. I was ready to file a bugreport, when I noticed it was documented behaviour.

By Casper Langemeijer

Take a look at the following code:

function b() 
{
global $a;
$b = 'bar';
$a = &$b;
}

$a = 'foo';
b();
echo $a;

What do you think is the value of $a after calling b()? The correct answer is 'foo'. If we remove the ampersand in '$a = &$b;' the value will be: 'bar'.

This behaviour can be explained as following:

In function b() the 'global $a' statement creates new a local variable $a as a reference to the global $a variable. '$a = &$b' then changes the local $a variable as a reference to $b. The global $a variable is not touched.

To achieve a sane result use the following construction, create the reference first, then assign a new value:

function b() 
{
global $a;
$b = &$a
$b = 'bar';
}

I still think this should be considered flawed implementation, if not simply broken.

« Back

Reactions on "PHP myths confused"

Taco
Placed on: 12-18-2008 18:37
Taco van den Broek
User icon
I'd like to correct your article: the corect answer to "What do you think is the value of $a after calling b()?" is "baz" in my case Wink

Nice post!
garfix
Placed on: 12-18-2008 20:30
Patrick van Bergen
User icon
to be continuum
Thanks Casper, your explanation is very clear Smile
Edited
garfix has edited this message on: 12-18-2008 20:30
Loïc Hoguin
Placed on: 12-19-2008 00:14
I wouldn't recommend using global variables in a function, and would recommend even less using references to global variables. But if I had no choice I'd rather use the $GLOBALS array. It may be a bit longer to write but it is easier to read and it doesn't suffer from this problem.

The implementation works as expected according to your (very clear) explanation, but it sure is misleading when you don't know exactly how the global keyword works.
Casper Langemeijer
Placed on: 12-19-2008 09:11
User icon
Thanks for your comment Loïc. And I agree that using the $GLOBALS superglobal is more clear, but only because the behaviour I describe in my article is not what you'd expect.

I don't like using $GLOBALS though. Using the global keyword is similar to the way other languages solve the same problem. The concept of superglobals only exists in the PHP language.
David Otton
Placed on: 12-24-2008 04:56
I hit the same thing about a month back, and came to the same conclusion as you ("it's broken!"). A guy called pestaa popped up in the comments and gave me a pretty clear explanation. It boils down to "it's a reference, not a pointer".

Link: http://www.otton.org/200...ces-globals-workaround/

Log in to comment on news articles.