Functions provide a way to group together related statements into a cohesive block. For reusable code, a function saves duplicating statements and makes maintenance of the code easier.
We’ve already presented many examples of function calls in this chapter. Once written, a user-defined function is called in exactly the same way. Consider an example of a simple user-developed function as shown in Example 2-6.
Example 2-6. A user-defined function to output bold text
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Simple Function Call</title> </head> <body bgcolor="#ffffff"> <?php function bold($string) { echo "<b>" . $string . "</b> "; } // First example function call (with a static string) echo "this is not bold "; bold("this is bold"); echo "this is again not bold "; // Second example function call (with a variable) $myString = "this is bold"; bold($myString); ?> </body></html>
The script defines the function bold( )
, which
takes one parameter, $string
, and prints that
string prefixed by a bold <b>
tag and
suffixed with a </b>
tag. The
bold( )
function, defined here, can be used with
a string literal expression or a variable, as shown.
Functions can also return values. For example, consider the following
code fragment that declares and uses a function heading( )
,
which returns a string using the return
statement:
function heading($text, $headingLevel) { switch ($headingLevel) case 1: $result = "<h1>" . ucwords($text) . "</h1>"; break; case 2: $result = "<h2>" . ucwords($text) . "</h2>"; break; case 3: $result = "<h3>" . ucfirst($text) . "</h3>"; break; default: $result = "<p><b>" . ucfirst($text) . "</b>"; return($result); } $test = "user defined functions"; echo heading($test, 2);
The function takes two parameters: the text of a heading and a
heading level. Based on the value of
$headingLevel
, the function builds the HTML
suitable to display the heading—changing the case of the
$text
appropriately. The previous fragment
generates the string:
<h2>User Defined Functions</h2>
The variable that is returned by a return
statement can optionally be placed in parentheses: the statements
return($result)
and return $result
are identical.
The argument and return types of a function aren’t declared when the function is defined. PHP allows arguments of any type to be passed to the function, and as with variables, the return type is determined when a result is actually returned. Consider a simple function that divides two numbers:
function divide($a, $b) { return ($a/$b); } $c = divide(4, 2); // assigns an integer value = 2 $c = divide(3, 2); // assigns a float value = 1.5 $c = divide(4.0, 2.0); // assigns a float value = 2.0
If the types of arguments passed to the function are critical, they should be tested as shown earlier in Section 2.1.3.
Variables used inside a function are different from those used outside a function. The variables used inside the function are limited to the scope of the function (there are exceptions to this rule, which are discussed later in this section). Consider an example that illustrates variable scope:
function doublevalue($var) { $temp = $var * 2; } $variable = 5; doublevalue($variable); echo "$temp is: $temp";
This example outputs the string:
$temp is:
and no value for $temp
. The scope of the variable
$temp
is local to the function
doublevalue( )
and is discarded when the function returns.
The PHP script engine doesn’t complain about undeclared variable being used. It just assumes the variable is empty. However, this use of an undefined variable can be detected using the error-reporting settings discussed later, in Section 2.12.
If you want to use a value that is local to a function elsewhere in a
script, the easiest way to do so is to return
the
value of the variable. This example achieves this:
function doublevalue($var) { $returnVar = $var * 2; return($returnVar); } $variable = 5; $temp = doublevalue($variable); echo "$temp is: $temp";
The example prints:
$temp is: 10
You could have still used the variable name $temp
inside the function doublevalue( )
. However, the
$temp
inside the function is a different variable
from the $temp
outside the function. The general
rule is that variables used exclusively within functions are local to
the function, regardless of whether an identically named variable is
used elsewhere. There are two exceptions to this general rule:
variables passed by reference and those declared
global
in the function aren’t
local to the function.
If you want to use the same variable everywhere in your code,
including within functions, you can do so with the
global
statement. The
global
statement declares a variable within a
function as being the same as the variable that is used outside of
the function. Consider this example:
function doublevalue( ) { global $temp; $temp = $temp * 2; } $temp = 5; doublevalue( ); echo "$temp is: $temp";
Because $temp
is declared inside the function as
global
, the variable $temp
used
in doublevalue( )
is a global variable that can
be accessed outside the function. Because the variable
$temp
can be seen outside the function, the script
prints:
$temp is: 10
A word of caution: avoid overuse of global
as it
makes for confusing code.
The global
variable declaration can be a trap.
In some other languages, global variables are usually declared global outside the functions and then used in the functions.
In PHP, it’s the opposite: to use a global variable
inside a function, declare the variable as global
inside the function.
An alternative to using global
is to return more
than one variable from a function by creating and returning an array
of values. A better approach is to pass parameters by reference
instead of by value. We discuss the latter approach in the next
section.
By default, variables are passed to functions by value, not by reference. The following example:
function doublevalue($var) { $var = $var * 2; } $variable = 5; doublevalue($variable); echo "$variable is: $variable";
has the output:
$variable is: 5
The parameter $variable
that is passed to the
function doublevalue( )
isn’t
changed by the function. What actually happens is that the value 5 is
passed to the function, doubled to be 10, and the result lost
forever! The value is passed to the function, not the variable
itself.
An alternative to returning a result or using a global variable is to pass a reference to a variable as an argument to the function. This means that any changes to the variable within the function affect the original variable. Consider this example:
function doublevalue(&$var) { $var = $var * 2; } $variable = 5; doublevalue($variable); echo "$variable is: $variable"; ?>
This prints:
$variable is: 10
The only difference between this example and the last one is that the
parameter $var
to the function
doublevalue( )
is prefixed with an ampersand
character: &$var
. The ampersand means that a
reference to the original variable is passed as the parameter, not
just the value of the variable. The result is that changes to
$var
in the function affect the original variable
$variable
outside the
function.
Functions that are defined with arguments that are references to variables can’t be called with literal expressions, because the function expects a variable to modify. PHP reports an error when such a call is made.
Referencing with the ampersand can also be used when assigning variables, which allows the memory holding a value to be accessed from more than one variable. This example illustrates the idea:
$x = 10; $y = &$x; $y++; echo $x; echo $y;
Here’s how it prints:
11 11
Because $y
is a reference to
$x
, any change to $y
affects
$x
. In effect, they are the same variable. So, by
adding 1 to $y
, you also add 1 to
$x
, and both are equal to 11.
The reference $y
can be removed with:
unset($y);
This has no effect on $x
or its value.
PHP allows functions to be defined with default values for arguments.
A default value is simply supplied in the argument list using the
=
sign. Consider the modified heading( )
function described earlier:
function heading($text, $headingLevel = 2) { switch ($level) case 1: $result = "<h1>" . ucwords($text) . "</h1>"; break; case 2: $result = "<h2>" . ucwords($text) . "</h2>"; break; case 3: $result = "<h3>" . ucfirst($text) . "</h3>"; break; default: $result = "<p><b>" . ucfirst($text) . "</b>"; return($result); } $test = "user defined functions"; echo heading($test);
When calls are made to the heading( )
function,
the second argument can be omitted, and the default value 2 is
assigned to the $headingLevel
variable.
To use functions across many PHP scripts,
PHP supports the include
statement and the
require
directive.
If you decide you wish to reuse the bold( )
function from
Example 2-6 in more than one script, you can store
it in an include file. For example, you can create a file called
functions.inc
and put the bold( )
function in the file:
<?php function bold($string) { echo "<b>" . $string . "</b> "; } ?>
Any PHP code in an include file must be surrounded by the PHP start and end script tags. The PHP script engine treats the contents of include files as HTML unless script tags are used.
In a script, you can then use the include
statement to provide access to the function bold( )
:
<html> <head> <title>Simple Function Call</title> </head> <body bgcolor="#ffffff"> <? include "functions.inc"; // First example function call (with a static string) echo "this is not bold "; bold("this is bold"); echo "this is again not bold "; // Second example function call (with a variable) $myString = "this is bold"; bold($myString); ?> </body></html>
The script works as before, but the function bold( )
can now be reused across several scripts by including
functions.inc
. We use include files throughout
Chapter 4 through Chapter 13.
Be careful when using the
include
statement. Including the same file twice or declaring a function in
the script that is already in an include file causes PHP to complain
about the function being redefined.
The include
statement is treated in the same way
as other statements. For example, you can conditionally include
different files using the following code fragment:
if ($netscape == true) { include "netscape.inc"; } else { include "other.inc"; }
The file is included only if the include
statement
is executed in the script. The braces used in this example are
necessary: if they are omitted, the example doesn’t
behave as expected.
If a file must always be included, the require
directive should be used instead of include
. The
require
directive is processed before the script
is executed, and the contents of the required file are always
inserted in the script. This is useful for creating reusable HTML.
For example, if you want to add the same header or footer to every
page on a site—regardless of errors or other
problems—require
makes this easy and simple
to maintain.
Consider the following HTML fragment:
<hr><br>(c) 2001 Hugh E. Williams and David Lane
If you want this fragment at the base of every page, the fragment can
be stored in a file footer.inc
and the directive
added to the bottom of every script you develop:
require "footer.inc";
The benefit is that if you want to update the HTML footer, you need to do so in only one file.
3.141.25.41