Login

The PHP Scripting Language

This article describes the basics of the PHP scripting language, which is very easy to learn if you are familiar with any programming language. It is excerpted from chapter two of the book Web Database Applications with PHP and MySQL, written by Hugh E. Williams and David Lane (O’Reilly, 2004; ISBN: 0596005431).

This chapter is the first of three that focus on the PHP scripting language. This chapter describes the PHP language basics. Chapter 3 describes PHP’s support for arrays, strings, and other data types, and Chapter 4 introduces object-oriented programming in PHP.

If you’re familiar with any programming language, PHP should be easy to learn. If you have done no programming before, the pace of this chapter may be brisk but should still be manageable. PHP has a syntax similar to JavaScript, which many web designers have learned; both languages hark back to the classic C and Perl languages in syntax.

Condition and branch statements supported by PHP, including
if
,
if…else
, and the
switch
statements

Looping statements

User-defined functions

We conclude the chapter with a short example that puts many of the basic PHP concepts together.

Introducing PHP

The current version of PHP is PHP4 (Version 4.3.4). PHP5 is available for beta testing at the time of writing as Version 5.0.0b3. We discuss both versions in this chapter.

PHP is a recursive acronym that stands for PHP: Hypertext Preprocessor; this is in the naming style of GNU, which stands for GNU’s Not Unix and which began this odd trend. The name isn’t a particularly good description of what PHP is and what it’s commonly used for. PHP is a scripting language that’s usually embedded or combined with the HTML of a web page. When the page is requested, the web server executes the PHP script and substitutes in the result back into the page. PHP has many excellent libraries that provide fast, customized access to DBMSs and is an ideal tool for developing application logic in the middle tier of a three-tier application.

PHP Basics

Example 2-1 shows the first PHP script in this book, the ubiquitous “Hello, world.” It’s actually mostly HTML; the PHP is embedded near the end.

When requested by a web browser, the script is run on the web server and the resulting HTML document sent back to the browser and rendered as shown in Figure 2-1.

Figure 2-1.The output of Example 2-1 shown in the Netscape browser

Example 2-1 illustrates the basic features of a PHP script. It’s a mixture of HTML—in this case it’s mostly HTML—and PHP code. The PHP code in this example:

<?phpprint “Hello, world”
;
?>

simply prints the greeting, “Hello, world.”

The PHP script shown in Example 2-1 is rather pointless: we could simply have authored the HTML to include the greeting directly. Because PHP integrates so well with HTML, using PHP to produce static sequence of characters is far less compli
cated and less interesting than using other high-level languages. However, the example does illustrate several features of PHP:

A block of PHP code is embedded within HTML using the begin and end tags
<?php
and
?>
. Other begin and end tag styles can also be used, such as the HTML style that is used with JavaScript or other embedded scripts:
<scriptlanguage=”PHP”>
and
</script>
. There’s also a shorter style
<?
and
?>
. For consistency, we use only the
<?php
and
?>
style in this book.

Whitespace has no effect, except to aid readability for the developer. For example, the PHP could have been written succinctly as
<?phpprint “Hello, world”;?>
with the same effect. Any mix of whitespace characters—spaces, tabs, carriage returns, and so on—can be used to separate PHP statements.

A PHP script is a series of statements, each terminated with a semicolon. Our simple example has only one statement:
print “Hello, world”;
. PHP script can be anywhere in a file and interleaved with any HTML fragment. While Example 2-1 contains only one statement within one set of
<?php
and
?>
tags, statements can be distribute code across multiple blocks of code.

When PHP script is run, each block of code, including the start and end script tags
<?php
and
?>
is replaced with the output of the block.

When we present a few lines of code that are sections of larger scripts, we usually omit the start and end tags.

The point of learning PHP, of course, is to create pages that change, pages that contain dynamic content derived from user input or a database. The first step toward that goal is to introduce a variable, which is something that can change from run to run. In this chapter, we don’t use dynamic content. But we can show how to set a variable to a string as follows:

<?php $outputString = “Hello, world”; ?>

And then rewrite our script as follows:

<?php print $outputString; ?>

Because
$outputString
has been set to
Hello, world
, that string is printed as part of the surrounding HTML page.

The freedom to interleave blocks of PHP statements with HTML is one of the most powerful features of PHP. A short example is shown in Example 2-2; the variable
$outputString
is initialized before the start of the HTML document, and later this variable is output twice, as part of the
<title>
and
<body>
elements. We discuss more about variables and how to use them later in this chapter.

The flexibility to add multiple blocks of PHP to HTML can also lead to unwieldy, hard-to-maintain code. Care should be taken in modularizing code and HTML; we discuss how to separate code and HTML using templates in Chapter 7.

{mospagebreak title=Creating PHP scripts}

A PHP script can be written using plain text and can be created with any text editor, such as the Unix editors joe, vi, nedit, Emacs, or pico, or a Microsoft Windows editor such as Notepad or WordPad. There are also several special-purpose PHP programming editors available, and a well-maintained list of these can be found at http://phpeditors.linuxbackup.co.uk/.

If you save a PHP script in a file with a .php extension under the directory configured as Apache’s document root, Apache executes the script when a request is made for the resource. Following the installation instructions given in Appendixes A through C, the document root on a Unix machine is:

/usr/local/apache/htdocs/

and in a Microsoft Windows environment:

C:Program FilesEasyPHP1-7www

Consider what happens when the script shown in Example 2-1 is saved in the file example.2-1.php in the document root directory and you view the file in a Web browser on the same machine. Apache—when configured with the PHP module—executes the script when requests to the URLhttp://localhost/example.2-1.phpare made.

If you are working on a Unix host, and directory permissions don’t permit creation of files in the document root, it’s also possible to work in your user home directory. If the installation instructions in Appendixes A through C have been followed, a directory can be created beneath your Unix home directory and the permissions set so that the directory is readable by the web server. You can do this by running a terminal window and typing the following after the shell prompt (shown here as a
%
):

% mkdir ~/public_html% chmod a+rx ~/public_html

The example file can then be created with the filename:

~/public_html/example.2-1.php

The file can then be retrieved with the URL http://localhost/~ user/example.2-1.php, where user
is the userlogin name.

You can insert any of the code in this chapter into that file, or another one of your choice, and see what’s displayed by calling it up in a browser as we have shown.

Comments

Comments can be included in code using several styles used by high-level programming languages. This includes the following styles:

// This is a one-line comment# This is another one-line comment style/* This is how youcan create a multi-linecomment */

Outputting data with echo and print

The print statement used in Example 2-1 and Example 2-2 is frequently used and can output any type of data. The echo
statement can be used for the same purpose. Consider some examples:

print “Hello, world”;// echo works just the sam
e
echo “Hello, world”;// numbers can be printed with echo too
echo 123;// So can the contents of variables $outputString = “Hi!”;
echo $outputString;

The difference between
print
and
echo
is that
echo
can output more than one param
eter, each separated by a comma. For example,
echo
can print a string and an integer together in the one message:

// prints “The answer is 42
“
echo “The answer is “, 42;

The
print
and
echo
statements are also often seen with parentheses:

echo “hello”;// is the same asecho (“hello”);

Parentheses make no difference to the behavior of
print
. However, when they are used with
echo
, only one output parameter can be provided.

The
echo
and
print
statements can be used for most tasks and can output any combi
nation of static strings, numbers, arrays, and other variable types discussed later in this chapter. We discuss more complex output with printf( ) in the next chapter.

String Literals

One of the most common tasks in a PHP script is to output literal sequences of characters to create messages, headings, and other text that appear on HTML pages. A literal sequence of characters—a string literal or simply a string—can be included in a PHP script using quotation characters. PHP can create double- and single-quoted string literals:

print ‘This works’
;
print “just like this.”;

Because quotation marks are used to mark the start and end of strings, a quotation mark that is actually part of a string must be marked in some way. Marking a charac
ter so that it is treated as a normal character, instead of being part of the PHP syntax, is called escaping. Quotation marks can be escaped by putting a backslash before them:

print “This string has a “: a double quote!”
;
print ‘This string has a ‘: a single quote!’;

A simple alternative to including quotation marks in a string is to switch to the single-quotation style:

// And here are some strings that contain quotes
print “This string has a ‘: a single quote!”;
print ‘This string has a “: a double quote!’;

To include a backslash character in a double-quoted string, use the escaped sequence
\
. Tab, newline (line break), and carriage-return characters can be included in a double-quoted string using the escape sequences
t
,
n
, and
r
, respectively. Insert
ing the white space characters
t
, n
, and
r
is often useful to make output more readable, however as HTML, white space is generally disregarded.

Unlike many other languages, PHP allows newline characters to be included directly in a string literal. The following example shows the variable
$var
assigned with a string that contains a newline character:

This feature is used in later chapters to construct SQL statements that are easier to read in the PHP source code, for example:

$query = “SELECT max(order_id)
FROM orders
WHERE cust_id = $custID”;

Variable substitution

Variable substitution provides a convenient way to embed data held in a variable directly into string literals. PHP examines, or parses, double-quoted strings and replaces variable names with the variable’s value. The following example shows how:

PHP interprets the $ and the following non-space characters as the name of a vari
able to insert. To include the dollar signs in a double-quoted string you need to escape the variable substitution meaning with the backslash sequence
$
.

When the name of the variable is ambiguous, braces
{}
can delimit the name as shown in the following example:

$memory = 256;// No variable called $memoryMbyte
s
// Sets $message to “My computer has of RAM” $message = “My computer has $memoryMbytes of RAM”;// Works: braces are used delimit variable name
// Sets $message to “My computer has 256Mbytes of RAM”
$message = “My computer has {$memory}Mbytes of RAM”;

When the string literal containing the characters
$memoryMbytes
is parsed, PHP tries to substitute the value of the nonexisting variable
$memoryMbytes
. Braces are also used for more complex variables, such as arrays and objects:

print “The array element is {$array[“element”]}.”;
print “Mars is {$planets[‘Mars’][‘dia’]} times the diameter of the Earth”;
print “There are {$order->count} green bottles …”;

We explain arrays in the next chapter and objects in Chapter 4.

We recommend using the braces syntax when including variables in string literals. It makes your code more readable, and saves you the trouble of remembering to escape characters.

Single-quoted strings aren’t parsed in the same way as double-quoted strings for vari
able substitution. For example, the characters
$vehicle
and
$number
aren’t substituted in the following fragment of code:

When a PHP script is executed, the PHP engine starts by reading the script from a file. A file is simply a sequence of characters than are interpreted by PHP as statements, variable identifiers, literal strings, HTML, and so on. To correctly interpret these characters, PHP needs to know the character encoding of the file. Put more simply, PHP needs to know what each 8-bit sequence that makes up a character means.

In many cases, you won’t need to worry about character encoding. By default PHP reads the characters encoded to the ISO-8859-1 standard—a standard that is equivalent to 7-bit ASCII for the first 127 characters. The ISO-8859-1 encoding standard— also known as Latin-1 encoding—uses the next 128 characters to represent characters used in Western European languages. By default PHP scripts can include ISO-8859-1 characters directly, as the following fragment demonstrates:

$gesprächsnotiz =
“von Paulus Esterházy und Markus Hoff-Holtmannus”;

The
ä
and
á
characters in the previous example are represented by the 8-bit sequences
11100100
and
11100001
—the 228th and 225th characters from ISO-8859-1.

Sometimes, it’s not convenient to work with non-7-bit ASCII characters in an editor environment. Indeed, some programs can only handle 7-bit ASCII and ignore high-bit characters—characters with a leading “1”. You can include high-bit characters using an escape sequence to specify either a hexadecimal or octal value. Hexadecimal sequences start with x and are followed by two digits—00 to ff—to represent 256 characters. For example, the á character can be represented in a string literal with the hexadecimal sequence xe1 since e1 is the hexadecimal equivalent of
11100100
:

$translation
=
“von Paulus Esterhxe1zy und Markus Hoff-Holtmannus”;

Escape sequence can only be used in string literals—PHP does not allow us to repre
sent the variable
$gesprächsnotiz
as
$gesprxe4chsnotiz
.

Like PHP’s Zend engine, browsers need to know the character encoding of a page before the page can be correctly displayed. In this book we assume the default ISO-8859-1 character encoding, and accordingly we instruct browsers to use this encoding by including the mark-up as follows:

Other ISO-8859-x character encoding standards allow Cyrillic, Arabic, Greek, and Hebrew characters to be encoded, and a full description of these encoding standards can be found at http://en.wikipedia.org/wiki/ISO_8859.

PHP can be configured to support UTF-8; an 8-bit encoding method that can represent Unicode characters. The Unicode Standard describes a universal character encoding that defines over 49,000 characters from the world’s scripts. Unicode characters can also be encoded using UTF-16, a 16-bit encoding, however PHP does not support 16-bit characters. More information about the Unicode standard can be found at http://www.unicode.org.

Variables

Variables in PHP are identified by a dollar sign followed by the variable name. Variables don’t need to be declared before you use them; normally you just assign them a value to create them. The following code fragment shows a variable $var assigned the integer 15. Therefore,
$var
is defined as being of type integer.

$var = 15;

Variables in PHP are simple: when they are used, the type is implicitly defined—or redefined—and the variable implicitly declared.

Variable names are case-sensitive in PHP, so
$Variable
,
$variable
,
$VAriable
, and
$VARIABLE
are all different variables.

One of the most common sources of bugs in PHP is failing to detect that more than one variable has accidentally been created. The flexibility of PHP is a great feature but is also dangerous. We discuss in Chapter 14 how to set the error reporting of PHP so that it detects this type of error.

Types

Data exists in different types so that appropriate operations can be performed on it. For instance, numeric values can be manipulated with arithmetic operators such as addition and subtraction; whereas strings of characters can be manipulated by operations such as converting to uppercase. In this section, we introduce the basic types; their importance will become clear as we use data in more and more complex operations.

Data exists in differentso that appropriate operations can be performed on it. For instance, numeric values can be manipulated with arithmetic operators such as addition and subtraction; whereas strings of characters can be manipulated by operations such as converting to uppercase. In this section, we introduce the basic types; their importance will become clear as we use data in more and more complex operations.

PHP has four scalar types—boolean, float, integer, and string—and two compound types, array and object. PHP also supports null—a special type that is used when a variable doesn’t have a value.

Variables of a scalar type contain a single value. Variables of a compound type—array or object—are made up of multiple scalar values or other compound values.

Arrays are discussed in detail in the next chapter, and objects are discussed in Chapter 4. Other aspects of variables—including global variables and scope—are discussed later in this chapter.

Boolean variables are as simple as they get: they can be assigned either true or false. Here are two example assignments of a Boolean variable:

$variable = false
;
$test = true;

An integer is a whole number, while a float is a number that has an exponent and mantissa. The number 123.01 is a float, and so is 123.0, while the number 123 is an integer. Consider the following two examples:

// This is an integer
$var1 = 6;// This is a float
$var2 = 6.0;

A float can also be represented using an exponential notation:

// This is a float that equals 1120
$var3 = 1.12e3;// This is a float that equals 0.02
$var4 = 2e-2

You’ve already seen examples of strings earlier in the chapter. Here are two more example string variables:

$variable = “This is a string”;
$test = ‘This is also a string’;

Along with the value, the type of a variable can change over the lifetime of the vari
able. Consider an example:

$var = 15;$var = “Sarah the Cat”;

This fragment is acceptable in PHP. The type of
$var
changes from integer to string as the variable is reassigned. Letting PHP change the type of a variable as the context changes is very flexible and a little dangerous. Later in Working with Types, we show ways to avoid problems that can arise with loosely typed variables.

Constants

Constants associate a name with a scalar value. For example, the Boolean values true and false are constants associated with the values 1 and 0, respectively. It’s also common to declare constants in a script. Consider this example constant declaration:

define(“PI”, 3.14159);// This outputs 3.1415
9
print PI;

Constants aren’t preceded by a
$
character. They can’t be changed once they have been defined and they can be accessed anywhere in a script (regardless of where they are declared).

Constants are useful because they allow parameters internal to the script to be grouped. When one parameter changes—for example, if you define a new maxi
mum number of lines per web page—you can alter this constant parameter in only one place and not throughout the code.

PHP has a large number of built-in constants that a script can use. For example, the library of mathematical functions already include a definition of
M_PI
to hold the constant pi:

// This outputs 3.1415926535897932384
6
print M_PI;

By convention, constant names use uppercase characters, and predefined constants are often named to indicate the associated library. For example the constants defined for the mathematical functions library all start with
M_
. We introduce predefined con
stants as needed throughout this book.

{mospagebreak title=Expressions, Operators, and Variable Assignment}

We’ve already described simple examples of assignment, in which a variable is assigned the value of an integer, string, or value of some other data type. The value on the right side of the equal sign is actually the simplest example of an expression.

An expression is anything that can be reduced to a single value, for example the sum
1 + 2
is an expression with an integer value of 3. Expressions can be complex combinations of operators and values, just as in mathematics. Examples of expressions (the first involving integers, the second involving integers and one floating point number) are:

6 + 3 –
2
( 255.0 / 2 ) + 1

The basic syntax for expressions in PHP is taken from the C language and is familiar to someone who has worked in almost any high-level programming language. Here are some examples:

There are many mathematical functions available in the math library of PHP for more complex tasks. We introduce some of these in the next chapter.

String expressions can be created using the dot-operator (
.
) to concatenate two strings:

// Assign a string value to a variable
$var = “test string”;// Concatenate two strings using the
// dot operator to produce “test string” $var = “test” . ” string”;// Add a string to the end of another
// to produce “test string”
$var = “test”;
$var = $var . ” string”;// Here is a shortcut to add a string to
// the end of another
$var .= ” test”;

The following are all equivalent. The syntax you use is a matter of taste.

echo “test string”;
echo “test ” . “string”;
echo “test “, “string”;

The first contains a single string. The second contains an expression combining two strings, while the third contains two arguments to the
echo
command.

The values returned from functions and many statements can be used as expressions including a variable assignment. In the following example, the assignment
($x=42)
is used as an integer expression with the value of 42:

// assign both $y and $x the value 42
$y = ($x = 42);

The parentheses are not needed in the example above; however, they highlight the fact that
$x = 42
is an expression.

PHP automatically converts types when combining values in an expression. For example, the expression4 + 7.0
contains an integer and a float; in this case, PHP con
siders the integer as a floating-point number, and the result is of type float. The type conversions are largely straightforward; however, there are some traps, which are discussed later in this chapter.

Operator precedence

The term precedence in mathematics and programming refers to the decision concerning which operator is evaluated first. For instance, in the following expression, by convention, the multiplication operator is evaluated first, leading to a value of 32:

2 + 5 * 6

PHP defines the precedence of operators in an expression similar to how it is done in other languages. Multiplication and division occur before subtraction and addition, and so on. However, reliance on evaluation order leads to unreadable, confusing code. Rather than memorize the rules, we recommend you construct unambiguous expressions with parentheses, because parentheses have the highest precedence in evaluation.

For example, in the following fragment
$variable
is assigned a value of 32 because of the precedence of multiplication over addition:

$variable = 2 + 5 * 6;

But the result is much clearer if parentheses are used:

$variable = 2 + (5 * 6);

Conditions and Branches

Conditionals add control to scripts and permit choices. Different statements are executed depending on whether expressions are true or false. There are two branching statements in PHP: if
, with the optional
else
clause, and
switch
, usually with two or more
case
clauses.

if…else Statement

The if statement conditionally controls execution. The basic format of an if statement is to test whether a condition is true
and, if so, to execute one or more statements.

The following
if
statement executes the
print
statement and outputs the string when the conditional expression,
$var
is greater than 5, is
true
:

if ($var > 5)
print “The variable is greater than 5”;

The expressions used in the examples in this section compare integers. They can be used to compare strings but usually not with the expected results. If strings need to be compared, use the PHP string library functionstrcmp( ). It’s discussed in more detail in Chapter 3.

Multiple statements can be executed as a block by encapsulating the statements within braces. If the expression evaluates as
true
, the statements within the braces are executed. If the expression isn’t
true
, none of the statements are executed. Consider an example in which three statements are executed if the condition is
true
:

if ($var > 5
)
{
print “The variable is greater than 5.”;// So, now let’s set it to 5
$var = 5;
print “In fact, now it is equal to 5.”;}

Without the braces, an
if
statement executes only the single, immediately following statement when the conditional expression evaluates to
true
.

The
if
statement can have an optional
else
clause to execute a statement or block of statements if the expression evaluates as
false
. Consider an example:

if ($var > 5)
print “Variable greater than 5”;
else
print “Variable less than or equal to 5”;

It’s also common for the
else
clause to execute a block of statements in braces, as in this example:

if ($var < 5){
print “Variable is less than 5”;
print “———————–“;}
else
{print “Variable is equal to or larger than 5”;
print “————————————-“;
}

The indentation in the preceding example highlights the nested nature of the multi
ple tests. If consecutive, cascading tests are needed, the
elseif
statement can be used. The choice of which method to use is a matter of personal preference. This example has the same functionality as the previous example:

The switch statement can be used as an alternative to if to select an option from a list of choices. The following example executes different code for different integer values, or cases of the variable $menu
. A
case
clause is provided for values 1, 2, 3, and 4, with a
default
: case provided for all other values:

This example can be implemented with
if
and
elseif
, but the
switch
method is usu
ally more compact, readable, and easier to type. The use of
break
statements is important: they prevent execution of statements that follow in the
switch
statement and force execution to jump to the statement that follows the closing brace.

If
break
statements are omitted from a
switch
statement, you can get an unexpected result. For example, without the
break
statements, if the user chooses option 3, the script outputs:

You picked three. You picked four. You picked another option

These results are often a source of difficult-to-detect bugs; however, by intentionally omitting the
break
statement, you can group cases together as shown in the following
switch
statement:

While not mandatory, the
default
: case is useful when default processing is performed on all but selected special cases, or to handle unexpected values when expected values have corresponding cases.

Conditional Expressions

Now we’ll look at what can go inside the parentheses of an if statement, and other control statements. The most common conditional comparison is to test the equality or inequality of two expressions. Equality is checked with the double-equal operator, == ; if the value on the left-hand side is equal to the value on the right-hand side, then the expression evaluates to true
. The expression
($var == 3)
in the following example evaluates to true:

$var = 3;if ($var == 3)
print “Equals 3”;

Inequality is tested with the not-equals operator,
!=
. Both evaluate to a Boolean result of
true
or
false
.

If the equality operator == and the assignment operator = are unfamiliar, beware: they are easy to inadvertently interchange. This is a very common bug and hard to detect.

The value of the conditional expression (
$var = 1
) evaluates as true, because the expression takes its value from the value on the right hand side of the assignment operator; in this case 1. Here is an example of a common mistake, which overwrites the original value of the variable and always prints the statement:

if ($var = 1
)
print”Variable equals 1.”;

The error of incorrectly replacing an assignment with == is a far less common mistake. However, it’s also difficult to detect because an incorrectly written assignment of
$var == 1;
is quietly evaluated as true or false with no effect on
$var
.

Expressions can be combined with parentheses and with the Boolean operators
&&
(and) and
||
(or). For example, the following expression returns true and prints the message if $var is equal to 3 or $var2 is equal to 7:

if (($var == 3) || ($var2 == 7))
print “Equals 3 or 7”;

The following expression returns
true
and prints the message if
$var
equals 2 and
$var2
equals 6:

Interestingly, if the first part of the expression
($var == 2)
evaluates as
false
, PHP doesn’t evaluate the second part of the expression
($var2 == 6)
, because the overall expression can never be
true
; both conditions must be
true
for an
&&
(and) opera
tion to be
true
. Similarly, in the previous example, if
($var == 3)
, then there’s no need to check if
($var2 == 7)
.

This short-circuit evaluation property has implications for design; to speed code, write the expression most likely to evaluate as
false
as the left-most expression, and ensure that computationally expensive operations are as right-most as possible.

Never assume that expressions combined with the Boolean operators
&&
and
||
are evaluated. PHP uses short-circuit evaluation when determining the result of a Boolean expression.

Conditional expressions can be negated with the Boolean not operator !. The following example shows how an expression that tests if
$var
is equal to 2 or 6 is negated:

Unlike the
&&
and
||
operators,
!
works on a single value as the following example highlights:

// Set a Boolean variable
$found = false;// The following message is printed
if (!$found)print “Expression is true”;

More complex expressions can be formed through combinations of the Boolean operators and the liberal use of parentheses. For example, the following expression evaluates as
true
and prints the message if one of the following is
true: $var
equals 6 and
$var2
equals 7, or
$var
equals 4 and
$var2
equals 1.

As in assignment expressions, parentheses ensure that evaluation occurs in the required order.

Loops

Loops add control to scripts so that statements can be repeatedly executed as long as a conditional expression remains true. There are four loop statements in PHP: while, do…while
,
for
, and
foreach
. The first three are general-purpose loop constructs, while the foreach is used exclusively with arrays and is discussed in the next chapter.

while

The while loop is the simplest looping structure but sometimes the least compact to use. The while loop repeats one or more statements—the loop body—as long as a condition remains true. The condition is checked first, then the loop body is exe
cuted. So, the loop never executes if the condition isn’t initially
true
. Just as with the
if
statement, more than one statement can be placed in braces to form the loop body.

The following fragment illustrates the
while
statement by printing out the integers from 1 to 10 separated by a space character:

The difference between while and do…while is the point at which the condition is checked. In do…while, the condition is checked after the loop body is executed. As long as the condition remains
true
, the loop body is repeated.

You can emulate the functionality of the previous
while
example as follows:

The
for
loop statement has three parts separated by semicolons, and all parts are optional:

Initial statements

Statements that are executed once, before the loop body is executed.

Loop conditions

The conditional expression that is evaluated before each execution of the loop body. If the conditional expression evaluates as false, the loop body is not exe
cuted.

End-loop statements

Statements that are executed each time after the loop body is executed.

The previous code fragment has the same output as our
while
and
do…while
loop count-to-10 examples.
$counter=1
is an initial statement that is executed only once, before the loop body is executed. The loop condition is
$counter<11
, and this is checked each time before the loop body is executed; when the condition is no longer
true
(when
$counter
reaches 11) the loop is terminated. The end-loop statement
$counter++
is executed each time after the loop body statements.

Our example is a typical
for
loop. The initial statement sets up a counter, the loop condition checks the counter, and the end-loop statement increments the counter. Most
for
loops used in PHP scripts have this format.

Conditions can be as complex as required, as in an
if
statement. Moreover, several initial and end-loop statements can be separated by commas. This allows for complexity:

for($x=0,$y=0; $x<10&&$y<$z; $x++,$y+=2)

However, complex
for
loops can lead to confusing code.

{mospagebreak title=Changing Loop Behavior}

To break out of a loop early—before the loop condition becomes false—the break statement is useful. This example illustrates the idea:

for($x=0; $x<100; $x++)
{
if ($x > $y)
break;
print $x;
}

If
$x
reaches 100, the loop terminates normally. However, if
$x
is (or becomes) greater than
$y
, the loop is terminated early, and program execution continues after the closing brace of the loop body. The
break
statement can be used with all loop types.

To start again from the top of the loop without completing all the statements in the loop body, use the
continue
statement. Consider this example:

The example prints and increments
$x
each time the loop body is executed. If
$x
is greater than
$y
, the sequence starts again with the
print $x
; statement (and
$x
keeps the value that was assigned to it during the loop). Otherwise,
$y
is printed and the loop begins again normally. Like the
break
statement,
continue
can be used with any loop type.

The use of
break
and
continue
statements to change loop behavior makes code harder to understand and should be avoided.

Functions

A function is another concept that programming derived from mathematics. Some programming functions are direct implementations of common mathematical functions, such as sines and other trigonometric functions. (Naturally, these are not used much in PHP.) But you are sure to use functions related to strings, dates, and other everyday objects in your code. PHP has a large number of useful functions built in, and you can define your own functions as we describe later in this chapter.

Functions are called in PHP scripts and can often be used as expressions. For instance, the following example uses the strtoupper( ) function to change a string to uppercase:

$var = “A string”;print strtoupper($var); // prints “A STRING”

A function is followed by parentheses, which can contain zero or more parameters. This function accepts just one parameter. It can be summarized as follows:

string strtoupper(string subject)

The previous statement is called a prototype and is very useful for introducing functions. Prototypes are used throughout PHP documentation, and the following chapters of this book, when a function is described. The first word indicates what is returned by the function: in this case, its output is a string. The name of the function follows, and then a list of parameters within parentheses. Each parameter is described by a type and a parameter name—strtoupper( ) is defined with a single string parameter named subject. Names allow us to distinguish multiple parameters when we describe the function.

Prototypes use brackets to indicate that function parameters that are optional. Consider the following prototype for the date( ) function:

string date(string format [, integer timestamp])

The date( ) function returns the current date and time as a string where the format is specified by the parameter format. The optional integer parameter timestamp allows non-current dates and times to be formatted. We discuss the date( ) function and timestamps in the next chapter.

When there is more that one optional parameter, then the parameters are shown in nested brackets:

string x(string p1 [, integer p2 [, integer p3]])

The fictional function x( ) must be called with at least p1, but optionally p2 and p3. The nesting of brackets indicates that parameter p3 can’t be included without p2.

Some functions allow an unspecified number of parameters; these are indicated with three periods:

string y(string p1 , …)

Working with Types

PHP is a loosely typed language, allowing variables and function parameters to be set to any type of data. Similarly, functions can return different data types in different circumstances.

In the last section, we introduced the function prototype as a way of describing the type of parameters that functions are designed to work with and the types of data that are returned. Since PHP is loosely typed, PHP can’t enforce these types as strongly typed languages do. To illustrate this, the PHP library function strtoupper( ) is designed to operate on strings, but can be called with an integer parameter:

$var = 42;print strtoupper($var); // prints the string “42”

When functions are designed to work with different data types, prototypes describe parameters and return values as mixed. Other functions may not work as expected, or may not work at all, when the wrong type of data is used.

Type Conversion

PHP provides several mechanisms to allow variables of one type to be considered as another type. Variables can be explicitly converted to another type with the following functions:

Because the string
“abc”
doesn’t look anything like an integer, the first call to the intval( ) function sets
$value
to zero.

PHP also supports type conversion with type-casting operators in much the same way as C, to allow the type of an expression to be changed. When you place the type name in parentheses in front of a variable, PHP converts the value to the desired type:

In the previous example, type casting, and calls to the strval( ), intval( ), and floatval( ) functions don’t change the value or type of the variable
$var
. The settype( )function actually modifies the variable that it is called with. For example:

// cast to an integer: the following are equivalent
$var = 39;// $var is now a string
settype($var, “string”);

The rules for converting types are mostly common sense, but some conversions may not appear so straightforward. Table 2-1 shows how various values of
$var
are con
verted using the
(int)
,
(bool)
,
(string)
, and
(float)
casting operators.

Table 2-1. Examples of type conversion in PHP

Value of $var

(int) $var

(bool) $var

(string) $var

(float) $var

null

0

false

“”

0

true

1

true

“1”

1

false

0

false

“”

0

0

0

false

“0”

0

3.8

3

true

“3.8”

3.8

“0”

0

false

“0”

0

“10”

10

true

“10”

10

“6 feet”

6

true

“6 feet”

6

“foo”

0

true

“foo”

0

{mospagebreak title=Automatic Type Conversion}

Automatic type conversion occurs when two differently typed variables are combined in an expression or when a variable is passed as an argument to a library function that expects a different type. When a variable of one type is used as if it were another type, PHP automatically converts the variable to a value of the required type. The same rules are used for automatic type conversion as demonstrated previously in Table 2-1.

Some simple examples show what happens when strings are added to integers and floats, and when strings and integers are concatenated:

Care must be taken when interpreting non-Boolean values as Boolean. Many library functions in PHP return values of different types in dif
ferent circumstances. For example, many functions return the Boolean value false if a valid result could not be determined. If the function is successful, they return the valid integer, string, or compound type. However, a valid return value of 0, 0.0,
”
0
”
, an empty string, null, or an empty array is also equal to the Boolean value false and can be misinterpreted as failure.

The solution is to test the type of the variable using the functions described in the next section.

Examining Variable Type and Content

Because PHP is flexible with types, it provides the following functions that can check a variable’s type:

All the functions return a Boolean value of
true
or
false
depending on whether the type of variable matches the variable type that forms the name of the function. For example, is_float( ) evaluates to
true
in the following code:

$test = 13.0;// prints “Variable is a float
“
if (is_float($test))print “Variable is a float”;

Is-identical and is-not-identical operators

While the PHP equals operator == tests the values of two variables, it doesn’t test the variables types. Consider the comparisons of string and integer variables:

$stringVar = “10 reasons to test variable type”;
$integerVar = 10;// Prints “Variables have the same value”
if ($stringVar == $integerVar)print “Variables have the same value”;

Because of PHP’s automatic type conversion,
$stringVar == $integerVar
evaluates to
true
. PHP provides the is-identical operator
===
that tests not only values, but types. In the fragment below, the expression
$stringVar === $integerVar
evaluates to
false
:

$stringVar = “10 reasons to test variable type”;
$integerVar = 10;// Does not print anything
if ($stringVar === $integerVar)print “Variables have the same value and type”;

PHP also provides the is-not-identical operator,
!==
, that returns
true
if the value or type of two expressions are different.

Debugging with gettype(), print_r(), and var_dump( )

PHP provides the gettype( ), print_r( ), and var_dump( )functions, which print the type and value of an expression in a human-readable form:

These functions are useful for debugging a script, especially when dealing with arrays or objects. To test the value and type of
$variable
at some point in the script, the fol
lowing code can be used:

$variable = “3 Blind mice” + 39
;
var_dump($variable);

This prints:

int(42)

While the var_dump( ) function allows multiple variables to be tested in one call, and provides information about the size of the variable contents, print_r( ) provides a more concise representation of arrays and objects, and will prove useful later when we start to use those variables.

The gettype( ) function simply returns the type name for an expression:

The name that gettype( ) returns should only be used for information and not to pro
grammatically test the type of a variable as the output is not guaranteed to remain stable with future PHP releases. To programmatically test a variable type, you should use the is_int( ), is_float( ), is_bool( ), is_string( ), is_array( ), or is_object( ) functions described earlier.

The gettype( ), print_r( ), and var_dump( ) functions can be used on variables and expressions of any type, and we use them throughout the book to help illustrate the results of our examples.

Testing, setting, and unsetting variables

During the running of a PHP script, a variable may be in an unset state or may not yet be defined. PHP provides the isset( ) function and the empty( ) language construct to test the state of variables:

boolean isset(mixed var)boolean empty(mixed var)

isset( ) tests if a variable has been set with a non-null value, while empty( ) tests if a variable is equal to false. The two are illustrated by the following code:

After the call to
unset
in the following example,
$var
is no longer defined:

$var = “foo”;// Later in the script
unset($var);// Does not print
if (isset($var)) print “Variable is Set”;

Table 2-2 show the return values for
isset($var)
and
empty($var)
when the variable
$var
is tested. Some of the results may be unexpected: when
$var
is set to
“0
,
”
empty( ) returns
true
.

Table 2-2. Expression values

State of the variable $var

isset($var)

empty($var)

unset $var;

false

true

$var = null;

false

true

$var = 0;

true

true

$var = true;

true

false

$var = false;

true

true

$var = “0”;

true

true

$var = “”;

true

true

$var = “foo”;

true

false

$var = array();

true

true

A variable is always set when it is assigned a value—with the exception of a null assignment—and isset( ) returns
true
. The empty( ) function tests the Boolean value of the variable and returns true if the variable is
false
. The statement

$result = empty($var);

is equivalent to

$result = not (boolean) $var;

However, PHP issues a warning when a cast operator is used on an unset variable, whereas empty( ) doesn’t.

{mospagebreak title=User-Defined Functions}

User-defined 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. Consider an example of a simple user-developed function as shown in Example 2-3.

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 parame
ter
$string
is a variable that is available in the body of the function, and the value of
$string
is set when the function is called. As shown in the example, the function can be called with a string literal expression or a variable as the parameter.

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:

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. The example outputs the string:

<h2>User-defined Functions</h2>

The variable that is returned by a
return
statement can optionally be placed in paren
theses: the statements
return($result)
and
return $result
are identical.

Parameter Types and Return Types

The parameter and return types of a function aren’t declared when the function is defined. PHP allows parameters 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);
}

The value returned from the function divide( ) is the value of the expression
($a/$b)
. The type that is returned depends on the parameters passed to divide( ). For example:

If the types of parameters passed to the function are critical, they should be tested as shown earlier in “Type Conversion.”

The
return
statement causes the execution of the function to end. To illustrate this, consider an improved divide( ) function definition that tests the parameter
$b
to avoid divide-by-zero errors:

function divide($a, $b)
{
if ($b == 0)
return false;return ($a/$b);
}

If
$b
is 0, then the function returns
false
and the division of
$a/$b
is never executed.

The
return
statement can also be used to exit from functions that don’t return val
ues. Consider the following definition of bold( ) that simply prints the parameter
$string
without any bold mark-up when passed non-string values:

Variables used inside a function are different from those used outside a function. The variables used inside the function are limited to use within the function. This is called the scope of the variable. There are exceptions to this rule, which are discussed later in this section. Consider an example that illustrates variable scope:

with 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 an undeclared variable being used. It just assumes the variable is empty. However, this use of an undefined variable can be detected by configuring the error-reporting settings. Error reporting is discussed in Chapter 14.

The easiest way to use a value that is local to a function elsewhere in a script is to return the value from the function with the
return
statement. The calling script can simply assign the returned value to a local variable. The following example does this:

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 else
where. There are three exceptions to this general rule: variables passed by reference, variables declared
global
in the function, and superglobals that contain user and environment values and are automatically created by PHP at runtime. Global variables are discussed in the next section, and superglobals are discussed in Chapter 6.

Global variables

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:

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 for experienced program
mers. 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.

Allowing a function to modify global variables solves the problem that a
return
statement can only pass back one value. An alternative to using
global
is to return an array of values—this approach becomes clear when we discuss arrays in Chapter 3. A better approach is to pass parameters by reference instead of by value, a practice described later.

{mospagebreak title=Static variables}

Variables can also be declared within a function as static. The static variable is available only in the scope of the function, but the value is not lost between function calls. Consider simple function count( ) that declares a static counter variable $count:

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.

Passing parameters by reference

An alternative to returning a result or using a global variable is to pass a reference to a variable as a parameter to the function. This means that any changes to the variable within the function affect the original variable. Consider this example:

The only difference between this example and the previous one is that the parameter
$var
to the function doublevalue( ) is prefixed with an ampersand character:
&$var
. The effect is a bit to hard to understand unless one learns low-level computer lan
guages, but it means that the parameter doesn’t contain the value of the variable—instead, it points to where the variable is stored in memory. The result is that changes to
$var
in the function affect the original variable
$variable
outside the function.

If a parameter is defined as a reference, you can’t pass the function a literal expression as that parameter because the function expects to modify a variable. PHP reports an error when the following is executed:

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++;
print $x;
print $y;

This fragment prints:

1111

Because
$y
is a reference to
$x
, any change to
$y
affects
$x
. In effect, they are the same variable. The reference
$y
can be removed with:

unset($y);

This has no effect on
$x
or its value.

Assigning variables with a reference to another variable can also be done with the ref
erence assignment operator
=&
with exactly the same outcome as shown in the previous example. The following fragment sets up three variables—
$x
,
$y
, and
$z
—that all point to the same value:

PHP allows functions to be defined with default values for parameters. A default value is simply supplied in the parameter list using the = sign. Consider the heading( )function described earlier; here we modify the function definition to include a default value:

When calls are made to the heading( ) function, the second argument can be omit
ted, and the default value 2 is assigned to the
$headingLevel
variable.

Reusing Functions with Include and Require Files

It’s valuable to be able to reuse functions in many scripts. PHP provides the include and require statements that allow you to reuse PHP scripts containing statements, function definitions, and even static HTML.

If you decide to reuse the bold( ) function from Example 2-3 in more than one script, you can store it in a separate include file. For example, you can create a file called functions.inc and put the bold( ) function in the file:

<?ph
p
function bold($string)
{print “<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.

Include files can also be used to incorporate resources such as static HTML or a set of variable initializations. The following example could be written to the file release.inc and included in all the scripts of an application:

<!– Beta Release Only –>
<?php
$showDebug = true;
?>

Both
include
and
require
read external include files, the only difference is in the behavior when a file can’t be included:
include
provides a warning whereas
require
terminates the script with a fatal error.

When you are including a file that contains user-defined functions, or other manda
tory content, you should use the
require
directive. We use the
require
directive in all of our code.

The
include
and
require
statements can be treated in the same way as other statements. For example, you can conditionally include different files using the following code fragment:

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.

Scripts can include more than one include file, and include files can themselves include other files. Writing scripts that use
include
or
require
can lead to an include file being included and evaluated twice. To avoid problems with variable reassign
ments and function redefinitions, PHP provides the
include_once
or
require_once
constructs statements that ensure that the contents of the file are included only once.

{mospagebreak title=Managing include files}

As you develop reusable code, you should consider how you will arrange your include files. By default, when a file is included using the include or require statements, PHP searches for the file in the same directory as the script being executed. You can include files in other directories by specifying a file path in the include or require statements. The following example shows how relative and absolute file paths can be used:

The paths can be specified with forward slashes for both Unix and Microsoft Win
dows environments, allowing scripts to be moved from one environment to another. However, using paths can make it difficult to change the directory structure of your application.

A more sophisticated, and flexible alternative to accessing include files is to set the
include_path
parameter defined in the php.ini configuration file. One or more directories can be specified in the
include_path
parameter, and when set, PHP will search for include files relative to those directories. The following extract from the php.ini file shows how to set the
include_path
parameter:

Path specifications for this parameter are system specific. Unix paths use the for
ward slash and are separated with the colon (:) character, while Microsoft Windows paths use the backslash and are separated by semi colons (;).

The php.ini configuration file defines many parameters that are used to define aspects of PHP’s behavior. Whenever you change php.ini, you need to restart your Apache web server so that the changes are re-read; instructions for restarting are in Appendix A.

If you set the
include_path
parameter,
include
and
require
directives need only specify a path relative to a directory listed in the
include_path
. For example, if the
include_path
is set to point at /usr/local/php/projectx, and you have an include file security.inc that’s stored in /usr/local/php/projectx/security, you only need to add:

include “security/security.inc”;

to your script file. The PHP engine will check the directory /usr/local/php/projectx, and locate the subdirectory security and its include file. Include files that are placed in directories outside of the web server’s document root are protected from accessed via the web server. In Chapter 6 we describe how to protect include files that are under the web server root directory.

For a large project, you might place the project-specific code into one directory, while keeping reusable code in another; this is the approach we use in our case study, Hugh and Dave’s Online Wines, as we describe in Chapter 15.

A Working Example

In this section, we use some of the techniques described so far to develop a simple, complete PHP script. The script doesn’t process input from the user, so we leave some of the best features of PHP as a web scripting language for discussion in later chapters.

Our example is a script that produces a web page containing the times tables. Our aim is to output the 1–12 times tables. The first table is shown in Figure 2-2 as rendered by a Mozilla browser.

Figure 2-2.The output of the times-tables script rendered in a Mozilla browser

The completed PHP script and HTML to produce the times tables are shown in Example 2-4. The first ten lines are the HTML markup that produces the
<head>
components and the
<h1> The Times Tables</h1>
heading at the top of the web page. Similarly, the last two lines are HTML that finishes the document:
</body>
and
</html>
.

Between the two HTML fragments that start and end the document is a PHP script to produce the times-table content and its associated HTML. The script begins with the PHP open tag
<?php
and finishes with the close tag
?>
.

The script is designed to process each times table and, for each table, to produce a heading and 12 lines. To do this, the script consists of two nested loops: an outer and inner
for
loop.

The outer
for
loop uses the integer variable
$table
, incrementing it by 1 each time the loop body is executed until
$table
is greater than 12. The body of the outer loop prints the heading and executes the inner loop that actually produces the body of each times table.

The inner loop uses the integer variable
$counter
to generate the lines of the times tables. Inside the loop body, the
$answer
to the current line is calculated by multiplying the current value of
$table
by the current value of
$counter
.

Every second line of the tables and the times-table headings are encapsulated in the bold tag
<b>
and bold end tag
</b>
, which produces alternating bold lines in the resulting HTML output. After calculating the
$answer
,an
if
statement follows that decides whether the line should be output in bold tags. The expression the
if
statement tests uses the modulo operator
%
to test if
$counter
is an odd or even number.

The modulo operation divides the variable
$counter
by 2 and returns the remainder. So, for example, if
$counter
is 6, the returned value is 0, because 6 divided by 2 is exactly 3 with no remainder. If
$counter
is 11, the returned value is 1, because 11 divided by 2 is 5 with a remainder of 1. If
$counter
is even, the conditional expression:

($counter % 2 == 0)

is
true
, and bold tags are printed.

Example 2-4 is complete but not especially interesting. Regardless of how many times the script is executed, the result is the same web page. In practice, you might consider running the script once, capturing the output, and saving it to a static HTML file. If you save the output as HTML, the user can retrieve the same page, with less web-server load and a faster response time.

In later chapters, we develop scripts with output that can change from run to run, and can’t be represented in a static file. In Chapter 6, we show scripts that interact with the MySQL database management system; the result is dynamic pages that change if the underlying data in the database is updated. We also show scripts that interact with the system environment and with user input from fill-in forms.