PHP has three variable scopes: the global scope, function scope, and class scope. The global scope is, as its name implies, available to all parts of the script; if you declare or assign a value to a variable outside of a function or class, that variable is created in the global scope.
40 ” Functions
However, any time you enter a function, PHP creates a new scope—a “clean slate” that, by default, contains no variable and that is completely isolated from the global scope. Any variable defined within a function is no longer available after the function has finished executing. This allows the use of names which may be in use elsewhere without having to worry about conflicts.
$a = "Hello World";
function hello() {
$a = "Hello Reader"; $b = "How are you"; }
hello();
echo $a; // Will output Hello World
echo $b; // Will emit a warning
There are two ways to access variables in the global scope from inside a function; the first consists of “importing” the variable inside the function’s scope by using the
globalstatement: $a = "Hello"; $b = "World"; function hello() { global $a, $b; echo "$a $b"; }
hello(); // Displays "Hello World"
You will notice that global takes a comma-separated list of variables to im- port—naturally, you can have multipleglobalstatements inside the same function.
Many developers feel that the use ofglobalintroduces an element of confusion into their code, and that “connecting” a function’s scope with the global scope can easily be a source of problems. They prefer, instead, to use the$GLOBALSsuperglobal array, which contains all the variables in the global scope:
$a = "Hello"; $b = "World";
function hello() {
echo $GLOBALS[’a’] .’ ’. $GLOBALS[’b’]; }
hello(); // Displays "Hello World"
Passing Arguments
Arguments allow you to inject an arbitrary number of values into a function in order to influence its behaviour:
function hello($who) {
echo "Hello $who"; }
hello("World");
/* Here we pass in the value, "World", and the function displays "Hello World" */
You can define any number of arguments and, in fact, you can pass an arbitrary num- ber of arguments to a function, regardless of how many you specified in its declara- tion. PHP will not complain unless you providefewer arguments than you declared. Additionally, you can make arguments optional by giving them a default value. Optional arguments must be right-most in the list and can only take simple val- ues—expressions are not allowed:
function hello($who = "World") {
echo "Hello $who"; }
hello();
42 ” Functions
Variable-length Argument Lists
A common mistake when declaring a function is to write the following:
function f ($optional = "null", $required) {
}
This does not cause any errors to be emitted, but it also makes no sense whatso- ever—because you will never be able to omit the first parameter ($optional) if you want to specify the second, and you can’t omit the second because PHP will emit a warning.
In this case, what you really want isvariable-length argument lists—that is, the ability to create a function that accepts a variable number of arguments, depending on the circumstance. A typical example of this behaviour is exhibited by theprintf()
family of functions.
PHP provides three built-in functions to handle variable-length argument lists:
func_num_args(), func_get_arg() and func_get_args(). Here’s an example of how they’re used:
function hello() {
if (func_num_args() > 0) {
$arg = func_get_arg(0); // The first argument is at position 0
echo "Hello $arg"; } else {
echo "Hello World"; }
}
hello("Reader"); // Displays "Hello Reader"
hello(); // Displays "Hello World"
You can use variable-length argument lists even if you do specify arguments in the function header. However, this won’t affect the way the variable-length argument list functions behave—for example,func_num_args()will still return thetotal number of arguments passed to your function, both declared and anonymous.
function countAll($arg1) {
if (func_num_args() == 0) {
die("You need to specify at least one argument"); } else {
$args = func_get_args(); // Returns an array of arguments
// Remove the defined argument from the beginning
array_shift($args); $count = strlen ($arg1);
foreach ($args as $arg) { $count += strlen($arg); }
}
return $count; }
echo countAll("foo", "bar", "baz"); // Displays ’9’
i
It is rather important to keep in mind that variable-length argument lists are full of potential pitfalls; while theyare very powerful, they do tend to make your code con-fusing, because it’s nearly impossible to provide comprehensive test cases if a function that accepts a variable number of parameters is not constructed properly.
Passing Arguments by Reference
Function arguments can also be passed by reference, as opposed to the traditional by-value method, by prefixing them with the by-reference operator&. This allows your function to affect external variables:
function countAll(&$count) {
if (func_num_args() == 0) {
die("You need to specify at least one argument"); } else {
44 ” Functions
// Remove the defined argument from the beginning
array_shift($args);
foreach ($args as $arg) { $count += strlen($arg); }
} }
$count = 0;
countAll($count, "foo", "bar", "baz"); // $count now equals 9
i
Note—and this is very important—that only variables can be passed as by-reference arguments; you cannot pass an expression as a by-reference parameter.Unlike PHP 4, PHP 5 allows default values to be specified for parameters even when they are declared as by-reference:
function cmdExists($cmd, &$output = null) { $output = ‘whereis $cmd‘;
if (strpos($output, DIRECTORY_SEPARATOR) !== false) { return true;
} else { return false; }
}
In the example above, the$outputparameter is completely optional—if a variable is not passed in, a new one will be created within the context ofcmdExists()and, of course, destroyed when the function returns.
Summary
Functions are one of the most often used components of the PHP language (or, for that matter, of any language). Without them, it would be virtually impossible to write reusable code—or even use object-oriented programming techniques.
For this reason, you should be well versed not only in the basics of function dec- laration, but also in the slightly less obvious implications of elements like passing arguments by reference and handling variable-length argument lists. The exam fea- tures a number of questions centered around a solid understanding of how functions work—luckily, these concepts are relatively simple and easy to grasp, as illustrated in this chapter.