Variable Scopes and References

We already introduced variable scope while looking at how variables behave in functions, but there’s much more to learn about it. In the video on functions, I hinted that there are ways to access and modify variables declared in the main script from within your function. Actually, there are three specific ways to do this.

Now, I want to get terms straight at the beginning. Variables defined outside of functions are said to be in the global scope, and variables defined inside of functions are said to be in that function’s local scope. I’ll use those terms throughout the rest of this video.

Now, there are actually two different ways to access variables in the global scope from within your function. The first way is to use the special PHP keyword ‘global’.

So, here we have a function that doesn’t take any arguments. Check it out:

function doSomethingGlobal() {
global $var1;
$var1++;
}

$var1 = 10;
doSomethingGlobal();
echo ‘$var1 is ‘ . $var1;

{show output}

With the global keyword, the PHP engine looks for a variable named $var1 in the global scope, and if it finds it, it uses a reference to that actual variable anywhere inside the function that it gets called. So, when I make a change inside the function, that change is reflected when I check $var1’s value later.

{show output}

And if it doesn’t find it, it creates a new entry in the global scope. So, we can actually make new global scope variables from within the local scope of a function this way:

function doSomethingGlobal() {
global $var1;
$var1 = 15;
$var1++;
}
doSomethingGlobal();
echo ‘$var1 is ‘ . $var1;

So here $var1 isn’t declared before the function gets called, but after running this function the outer code can access $var1 and get its value.

{show output}

When using the global keyword on multiple variables, I can use just one line by separating each variable name after the global keyword with commas.

There is another way to use global variables however, and that’s by using what are known as super-globals. These are arrays that are available in all contexts. However, there’s only one super-global array that I want to talk about here. Others will be introduced in later videos as we look at topics where they’re relevant.

$GLOBALS;

$GLOBALS, in all caps, is an array containing all of the global-scope variables in your script. In order to access a variable in the global scope from within the local scope of a function, use the name of the variable as a key, and the value in $GLOBALS will be the value of the variable it refers to. So, let’s rewrite our function again, this time using the $GLOBALS super-global array:

function doSomethingGlobal() {
$GLOBALS[‘var1’]++;
}

{show output}

Basically, all I’ve done is treat $GLOBALS[‘var1’] as though it were the variable, $var1, and then incremented it. The other cool thing about this, is that just like using the global keyword, using the $GLOBALS super-global lets me create new variables in the global scope:

function doSomethingGlobal() {
$GLOBALS[‘var1’] = 10;
}
echo ‘$var1 is ‘ . $var1;

{show output}

So, that’s how global variables work. In later videos we’ll look at other super-global arrays that are useful for different tasks, but all of them can be accessed in any context without using the ‘global’ keyword.

The last method for accessing a global variable inside a function’s local scope is through what’s called ‘pass-by-reference’. I mentioned the reference operator, the &, briefly in the video on foreach loops. You may recall that by placing an & in front of the name assigned to each value as you iterated over an array, your loop could actually change the values in the array. Well, you can use the same operator in the context of your functions’ argument lists, and it gives you the same ability – that is, you can alter the variables passed into your function, and the changes will be reflected in the global scope.

Technically, passing arguments by reference has nothing to do with variable scope, but it’s an important enough topic that I don’t want to move on before talking about it. When you call a function with a variable, as opposed to a literal, unless that variable is an object (and we talk about objects in a later chapter, so don’t dwell on this if you’re not familiar with them), but unless it’s an object, the variable that your function actually uses is the passed variable’s value, and not the passed variable itself. This is an important point, because it means that, as we’ve already seen, if you change the value of that variable within the function, nothing about the variable you sent from the line that called your function will be affected. That’s how things work normally. In programmer terms, we refer to this type of function call as ‘pass-by-value’.

Here’s a simple example of what happens when you change a variable within a function under a normal case:

function doSomething($var1) {
$var1++;
}

$var1 = 10;
doSomething($var1);
echo ‘$var1 is ‘ . $var1;

{show output}

Note that nothing changed about $var1. That’s because the two instances of $var1 exist in two different PHP symbol tables. However, PHP also supports something called ‘pass-by-reference’. This is what you use when you do want a change inside a function to affect a variable that was sent to the function. In order to do this, just put the reference operator, the &, inside your argument list in front of any variable you want passed by reference. Watch what happens:

{place & in front of $var1 in function argument list}

{show output}

So, what just happened? Well, the two instances of $var1 are still part of two different scopes. However, inside the function, the $var1 it uses is actually a reference to the first variable. So as far as the function is concerned, it can use its variable the exact same way as it did before when it was just passed by value, but now, if the function makes a change to its copy of $var1, the original $var1 also gets affected.

And by the way, I only named the variables the same to help make the concept easier to understand, but I can name it whatever I want inside the function and it’s still a reference to whichever variable was passed in through the function call:

{change $var1 in function to $someVar}

{show output}

See? Makes no difference what I call it – it’s still a reference.

However, even when passing by reference, PHP is still keeping the variables in two separate symbol tables, which is made a little more obvious when I can change its name.

Using the reference operator, it’s also possible to get a reference to a variable in other contexts. Let’s look at a final example:

$var1 = 10;
$var2 = $var1;
$var2++;
echo ‘$var1 is ‘ . $var1;

{show output}

Notice, $var2 is just a copy of the value and type in $var1, and not a reference to $var1 itself. Now, with the assignment operator watch what happens:

$var1 = 10;
$var2 = &$var1;
$var2++;
echo ‘$var1 is ‘ . $var1;

{show output}

This time, $var1 actually got updated too. And that’s because $var2 isn’t a copy of $var1’s value, but a reference to $var1. And when $var2 changes, it affects $var1.

If you want to de-reference your variables, you can use the special PHP function ‘unset’. It will set a variable to null without affecting the other variable:

$var1 = 10;
$var2 = &$var1;
unset($var2);
echo ‘$var1 is ‘ . $var1 . ‘<br>’;
echo ‘$var2 is ‘ . $var2;

{show output}

$var1 = 10;
$var2 = &$var1;
unset($var1);
echo ‘$var1 is ‘ . $var1 . ‘<br>’;
echo ‘$var2 is ‘ . $var2;

{show output}

February 12 2010 08:51 pm | Basics and PHP Programming Basics and PHP tutorial scripts

Trackback URI | Comments RSS

Leave a Reply