Lesson Weekend

Let's get this out of the way. You are about to learn about scope, and everyone is confused about it at first. If someone says they got it immediately, then they are a liar. It's really ok, you'll get it. With that in mind, take a breath, and here we go. We are going to go over a couple of common mistakes often caused by misunderstanding this idea of scope.

Scope is essentially a fancy word for the programming equivalent of "What happens in Vegas stays in Vegas." Except that instead of Vegas, we have curly brackets: {}.

I know, your brow just furrowed. Bear with me.

Let's make a function that adds 5 to any number. For input, it should take one number as an argument, and for output it should give us that number plus 5. Go into the PHP shell by typing php -a into your terminal, and try this out:

function addFive($a_number)
{
    $sum = 5 + $a_number;
    return $sum;
}
addFive(2); 
echo "The sum of 5 and 2 is: $sum";

It says that the sum of 5 and 2 is just blank space, and it gives us an error. Why? First, always look at your error messages - they are hints! Our error says "PHP Notice: Undefined variable: sum in php shell code on line 1". So from that we can figure out that for some reason our PHP pastry chef doesn't understand what $sum means in the last line of our program.

This is because the variable $sum was created inside of the function, so the rest of our code can't see it. We say that the variable $sum's scope is limited to the function addFive. So when we try to print $sum in the last line, the PHP pastry chef gives you an error thinking that $sum is a blank, unused variable that you forgot to set to something.

Anything you define inside of a function's set of curly brackets is only visible to code that is also inside of that set of curly brackets. Remember that just like Vegas, what happens inside a function, stays inside a function, unless you intentionally return it. (There are a couple exceptions to this rule, but you don't need them for a while.)

When the function addFive is run, the variable $sum is created, but when the function finishes running, that variable automatically evaporates back into the 'ether' of your computer's memory. So you can't use it later in your program outside of the function.

We can fix our example by storing the return value from our function in a variable, and then printing that:

function addFive($a_number)
{
    $sum = 5 + $a_number;
    return $sum;
}
$answer = addFive(2); 
echo "The sum of 5 and 2 is: $answer";

The variable $sum created inside the function is completely different from the variable $answer created outside of the function. What can be very confusing is that even if we named both of them $sum they would still be entirely separate variables:

function addFive($a_number)
{
    $sum = 5 + $a_number;
    return $sum;
}
$sum = addFive(2); 
echo "The sum of 5 and 2 is: $sum";

Take a moment to make sure you fully understand this: the $sum inside the addFive function is a completely different variable than the $sum outside the addFive function. They don't know about each other because they were created in different scopes.

Here's another example. Let's make a function which adds one number to another number.

$number_to_add = 5;
function addNumber($a_number)
{
    return $a_number + $number_to_add;
}
echo "The sum of 9 and $number_to_add is: ";
echo addNumber(9);

Why does it say that $number_to_add is an undefined variable? Because $number_to_add was defined outside of the function's curly brackets, the code inside of the function can't see it. So your function addNumber thinks that $number_to_add is just a new blank variable, and doesn't know what to do with it.

Variables need to have a scope so that they don't interfere with each other. When I'm thinking about variable scope, I like to think of my program as a house. At first it's just a studio apartment - it has one room. That one room is called the global scope. It is outside of all the curly brackets.

Any time I make a function, I am adding a room to the house. Each new room has walls made of curly brackets. Any variables created inside that new room can only stay in that room unless I tell them otherwise. Only code that lives inside that room can interact with variables created in that room. Likewise, variables created in the first room of the house, in the global scope, can't interact with variables inside of other rooms.

All right, that's a lot to take in! Let's recap.

  • By default, all variables created inside of functions are scoped to that function (they have what is also called function scope, or local scope).
  • Variables created outside of any curly brackets are in the global scope, but they are still local to that level of scope. By default, they can't see variables created inside of the function scope.