Programming PHPProgramming PHPSearch this book

2.3. Variables

Variables in PHP are identifiers prefixed with a dollar sign ($). For example:

$name
$Age
$_debugging
$MAXIMUM_IMPACT

A variable may hold a value of any type. There is no compile- or runtime type checking on variables. You can replace a variable's value with another of a different type:

$what = "Fred";
$what = 35;
$what = array('Fred', '35', 'Wilma');

There is no explicit syntax for declaring variables in PHP. The first time the value of a variable is set, the variable is created. In other words, setting a variable functions as a declaration. For example, this is a valid complete PHP program:

$day = 60 * 60 * 24;
echo "There are $day seconds in a day.\n";
There are 86400 seconds in a day.

A variable whose value has not been set behaves like the NULL value:

if ($uninitialized_variable === NULL) {
  echo "Yes!";
}
Yes

2.3.1. Variable Variables

You can reference the value of a variable whose name is stored in another variable. For example:

$foo = 'bar';
$$foo = 'baz';

After the second statement executes, the variable $bar has the value "baz".

2.3.2. Variable References

In PHP, references are how you create variable aliases. To make $black an alias for the variable $white, use:

$black =& $white;

The old value of $black is lost. Instead, $black is now another name for the value that is stored in $white:

$big_long_variable_name = "PHP";
$short =& $big_long_variable_name;
$big_long_variable_name .= " rocks!";
print "\$short is $short\n";
print "Long is $big_long_variable_name\n";
$short is PHP rocks!
Long is PHP rocks!
$short = "Programming $short";
print "\$short is $short\n";
print "Long is $big_long_variable_name\n";
$short is Programming PHP rocks!
Long is Programming PHP rocks!

After the assignment, the two variables are alternate names for the same value. Unsetting a variable that is aliased does not affect other names for that variable's value, though:

$white = "snow";
$black =& $white;
unset($white);
print $black;
snow

Functions can return values by reference (for example, to avoid copying large strings or arrays, as discussed in Chapter 3):

function &ret_ref() {     // note the &
   $var = "PHP";
   return $var;
}
$v =& ret_ref();          // note the &

2.3.3. Variable Scope

The scope of a variable, which is controlled by the location of the variable's declaration, determines those parts of the program that can access it. There are four types of variable scope in PHP: local, global, static, and function parameters.

2.3.3.1. Local scope

A variable declared in a function is local to that function. That is, it is visible only to code in that function (including nested function definitions); it is not accessible outside the function. In addition, by default, variables defined outside a function (called global variables) are not accessible inside the function. For example, here's a function that updates a local variable instead of a global variable:

function update_counter ( ) {
  $counter++;
}
$counter = 10;
update_counter( );
echo $counter;
10

The $counter inside the function is local to that function, because we haven't said otherwise. The function increments its private $counter, whose value is thrown away when the subroutine ends. The global $counter remains set at 10.

Only functions can provide local scope. Unlike in other languages, in PHP you can't create a variable whose scope is a loop, conditional branch, or other type of block.

2.3.3.2. Global scope

Variables declared outside a function are global. That is, they can be accessed from any part of the program. However, by default, they are not available inside functions. To allow a function to access a global variable, you can use the global keyword inside the function to declare the variable within the function. Here's how we can rewrite the update_counter( ) function to allow it to access the global $counter variable:

function update_counter ( ) {
    global $counter;
    $counter++;
}
$counter = 10;
update_counter( );
echo $counter;
11

A more cumbersome way to update the global variable is to use PHP's $GLOBALS array instead of accessing the variable directly:

function update_counter ( ) {
    $GLOBALS[counter]++;
}
$counter = 10;
update_counter( );
echo $counter;
11

2.3.3.3. Static variables

A static variable retains its value between calls to a function but is visible only within that function. You declare a variable static with the static keyword. For example:

function update_counter ( ) {
  static $counter = 0;
  $counter++;
  echo "Static counter is now $counter\n";
}
$counter = 10;
update_counter( );
update_counter( );
echo "Global counter is $counter\n";
Static counter is now 1
Static counter is now 2
Global counter is 10

2.3.3.4. Function parameters

As we'll discuss in more detail in Chapter 3, a function definition can have named parameters:

function greet ($name) {
  echo "Hello, $name\n";
}
greet("Janet");
Hello, Janet

Function parameters are local, meaning that they are available only inside their functions. In this case, $name is inaccessible from outside greet( ).

2.3.4. Garbage Collection

PHP uses reference counting and copy-on-write to manage memory. Copy-on-write ensures that memory isn't wasted when you copy values between variables, and reference counting ensures that memory is returned to the operating system when it is no longer needed.

To understand memory management in PHP, you must first understand the idea of a symbol table . There are two parts to a variable—its name (e.g., $name), and its value (e.g., "Fred"). A symbol table is an array that maps variable names to the positions of their values in memory.

When you copy a value from one variable to another, PHP doesn't get more memory for a copy of the value. Instead, it updates the symbol table to say "both of these variables are names for the same chunk of memory." So the following code doesn't actually create a new array:

$worker = array("Fred", 35, "Wilma");
$other = $worker;                        // array isn't copied

If you then modify either copy, PHP allocates the memory and makes the copy:

$worker[1] = 36;                         // array is copied, value changed

By delaying the allocation and copying, PHP saves time and memory in a lot of situations. This is copy-on-write.

Each value pointed to by a symbol table has a reference count, a number that represents the number of ways there are to get to that piece of memory. After the initial assignment of the array to $worker and $worker to $other, the array pointed to by the symbol table entries for $worker and $other has a reference count of 2.[1] In other words, that memory can be reached two ways: through $worker or $other. But after $worker[1] is changed, PHP creates a new array for $worker, and the reference count of each of the arrays is only 1.

[1]It is actually 3 if you are looking at the reference count from the C API, but for the purposes of this explanation and from a user-space perspective, it is easier to think of it as 2.

When a variable goes out of scope (as a function parameter or local variable does at the end of a function), the reference count of its value is decreased by one. When a variable is assigned a value in a different area of memory, the reference count of the old value is decreased by one. When the reference count of a value reaches 0, its memory is freed. This is reference counting.

Reference counting is the preferred way to manage memory. Keep variables local to functions, pass in values that the functions need to work on, and let reference counting take care of freeing memory when it's no longer needed. If you do insist on trying to get a little more information or control over freeing a variable's value, use the isset( ) and unset( ) functions.

To see if a variable has been set to something, even the empty string, use isset( ):

$s1 = isset($name);                    // $s1 is false
$name = "Fred";
$s2 = isset($name);                    // $s2 is true

Use unset( ) to remove a variable's value:

$name = "Fred";
unset($name);                          // $name is NULL


Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.