Previous Section  < Day Day Up >  Next Section

5.4 Understanding Variable Scope

As you saw in Example 5-9, changes inside a function to variables that hold arguments don't affect those variables outside of the function. This is because activity inside a function happens in a different scope. Variables defined outside of a function are called global variables. They exist in one scope. Variables defined inside of a function are called local variables. Each function has its own scope.

Imagine each function is one branch office of a big company, and the code outside of any function is the company headquarters. At the Philadelphia branch office, co-workers refer to each other by their first names: "Alice did great work on this report," or "Bob never puts the right amount of sugar in my coffee." These statements talk about the folks in Philadelphia (local variables of one function), and say nothing about an Alice or a Bob who works at another branch office (local variables of another function) or at company headquarters (global variables).

Local and global variables work similarly. A variable called $dinner inside a function, whether or not it's an argument to that function, is completely disconnected from a variable called $dinner outside of the function and from a variable called $dinner inside another function. Example 5-20 illustrates the unconnectedness of variables in different scopes.

Example 5-20. Variable scope
$dinner = 'Curry Cuttlefish';



function vegetarian_dinner( ) {

    print "Dinner is $dinner, or ";

    $dinner = 'Sauteed Pea Shoots'; 

    print $dinner;

    print "\n";

}



function kosher_dinner( ) {

    print "Dinner is $dinner, or ";

    $dinner = 'Kung Pao Chicken';

    print $dinner;

    print "\n";

}



print "Vegetarian ";

vegetarian_dinner( );

print "Kosher ";

kosher_dinner( );

print "Regular dinner is $dinner";

Example 5-20 prints:

Vegetarian Dinner is , or Sauteed Pea Shoots

Kosher Dinner is , or Kung Pao Chicken

Regular dinner is Curry Cuttlefish

In both functions, before $dinner is set to a value inside the function, it has no value. The global variable $dinner has no effect inside the function. Once $dinner is set inside a function, though, it doesn't affect the global $dinner set outside any function or the $dinner variable in another function. Inside each function, $dinner refers to the local version of $dinner and is completely separate from a variable that happens to have the same name in another function.

Like all analogies, though, the analogy between variable scope and corporate organization is not perfect. In a company, you can easily refer to employees at other locations; the folks in Philadelphia can talk about "Alice at headquarters" or "Bob in Atlanta," and the overlords at headquarters can decide the futures of "Alice in Philadelphia" or "Bob in Charleston." With variables, however, you can access global variables from inside a function, but you can't access the local variables of a function from outside that function. This is equivalent to folks at a branch office being able to talk about people at headquarters but not anyone at the other branch offices, and to folks at headquarters not being able to talk about anyone at any branch office.

There are two ways to access a global variable from inside a function. The most straightforward is to look for them in a special array called $GLOBALS. Each global variable is accessible as an element in that array. Example 5-21 demonstrates how to use the $GLOBALS array.

Example 5-21. The $GLOBALS array
$dinner = 'Curry Cuttlefish';



function macrobiotic_dinner( ) {

    $dinner = "Some Vegetables";

    print "Dinner is $dinner";

    // Succumb to the delights of the ocean

    print " but I'd rather have ";

    print $GLOBALS['dinner'];

    print "\n";

}

        

macrobiotic_dinner( );

print "Regular dinner is: $dinner";

Example 5-21 prints:

Dinner is Some Vegetables but I'd rather have Curry Cuttlefish

Regular dinner is: Curry Cuttlefish

Example 5-21 accesses the global $dinner from inside the function as $GLOBALS['dinner']. The $GLOBALS array can also modify global variables. Example 5-22 shows how to do that.

Example 5-22. Modifying a variable with $GLOBALS
$dinner = 'Curry Cuttlefish';



function hungry_dinner( ) {

    $GLOBALS['dinner'] .= ' and Deep-Fried Taro';

}



print "Regular dinner is $dinner";

print "\n";

hungry_dinner( );

print "Hungry dinner is $dinner";

Example 5-22 prints:

Regular dinner is Curry Cuttlefish

Hungry dinner is Curry Cuttlefish and Deep-Fried Taro

Inside the hungry_dinner( ) function, $GLOBALS['dinner'] can be modified just like any other variable, and the modifications change the global variable $dinner. In this case, $GLOBALS['dinner'] has a string appended to it using the concatenation operator from Example 2-19.

The second way to access a global variable inside a function is to use the global keyword. This tells the PHP interpreter that further use of the named variable inside a function should refer to the global variable with the given name, not a local variable. This is called "bringing a variable into local scope." Example 5-23 shows the global keyword at work.

Example 5-23. The global keyword
$dinner = 'Curry Cuttlefish';



function vegetarian_dinner( ) {

    global $dinner;

    print "Dinner was $dinner, but now it's ";

    $dinner = 'Sauteed Pea Shoots'; 

    print $dinner;

    print "\n";

}



print "Regular Dinner is $dinner.\n";

vegetarian_dinner( );

print "Regular dinner is $dinner";

Example 5-23 prints:

Regular Dinner is Curry Cuttlefish.

Dinner was Curry Cuttlefish, but now it's Sauteed Pea Shoots

Regular dinner is Sauteed Pea Shoots

The first print statement displays the unmodified value of the global variable $dinner. The global $dinner line in vegetarian_dinner( ) means that any use of $dinner inside the function refers to the global $dinner, not a local variable with the same name. So, the first print statement in the function prints the already-set global value, and the assignment on the next line changes the global value. Since the global value is changed inside the function, the last print statement outside the function prints the changed value as well.

The global keyword can be used with multiple variable names at once. Just separate each variable name with a comma. For example:

global $dinner, $lunch, $breakfast;

Generally, I recommend that you use the $GLOBALS array to access global variables inside functions instead of the global keyword. Using $GLOBALS provides a reminder on every variable access that you're dealing with a global variable. Unless you're writing a very short function, it's easy to forget that you're dealing with a global variable with global and become confused as to why your code is misbehaving. Relying on the $GLOBALS array requires a tiny bit of extra typing, but it does wonders for your code's intelligibility.


You may have noticed something strange about the examples that use the $GLOBALS array. These examples use $GLOBALS inside a function, but don't bring $GLOBALS into local scope with the global keyword. The $GLOBALS array, whether used inside or outside a function, is always in scope. This is because $GLOBALS is a special kind of pre-defined variable, called an auto-global . Auto-globals are variables that can be used anywhere in your PHP programs without anything required to bring them into scope. They're like a well-known employee that everyone, at headquarters or a branch office, refers to by his first name.

The auto-globals are always arrays that are automatically populated with data. They contain things such as submitted form data, cookie values, and session information. Chapter 6 and Chapter 8 each describe specific auto-global variables that are useful in different contexts.

    Previous Section  < Day Day Up >  Next Section