Tuesday, July 14, 2009

Beginning PHP and Oracle From Novice to Professional by W. Jason Gilmore and Bob Bryla Chapter 3

You’re only two chapters into the book and already quite a bit of ground has been covered. By now, you are familiar with PHP’s background and history and have delved deep into the installation and
configuration concepts and procedures. This material sets the stage for what will form the crux of much of the remaining material in this book: creating powerful PHP applications. This chapter initiates this discussion, introducing a great number of the language’s foundational features. Specif- ically, you’ll learn how to do the following:

• Embed PHP code into your Web pages

• Comment code using the various methodologies borrowed from the Unix shell scripting, C, and C++ languages
• Output data to the browser using the echo(), print(), printf(), and sprintf() statements

• Use PHP’s datatypes, variables, operators, and statements to create sophisticated scripts

• Take advantage of key control structures and statements, including if-else-elseif, while,
foreach, include, require, break, continue, and declare

By the conclusion of this chapter, you’ll possess not only the knowledge necessary to create basic but useful PHP applications, but also an understanding of what’s required to make the most of the material covered in later chapters.

■Note This chapter simultaneously serves as both a tutorial for novice programmers and a reference for experi-
enced programmers who are new to the PHP language. If you fall into the former category, consider reading the chapter in its entirety and following along with the examples.

Embedding PHP Code in Your Web Pages

One of PHP’s advantages is that you can embed PHP code directly alongside HTML. For the code to do anything, the page must be passed to the PHP engine for interpretation. But the Web server doesn’t just pass every page, rather, it passes only those pages identified by a specific file extension (typically
.php) as configured per the instructions in Chapter 2. But even selectively passing only certain pages
to the engine would nonetheless be highly inefficient for the engine to consider every line as a poten- tial PHP command. Therefore, the engine needs some means to immediately determine which areas of the page are PHP-enabled. This is logically accomplished by delimiting the PHP code. There are four delimitation variants, all of which are introduced in this section.

39

Default Syntax

The default delimiter syntax opens with <?php and concludes with ?>, like this:

<h3>Welcome!</h3>
<?php
echo "<p>Some dynamic output here</p>";
?>
<p>Some static output here</p>

If you save this code as test.php and execute it from a PHP-enabled Web server, you’ll see the output shown in Figure 3-1.

Figure 3-1. Sample PHP output

Short-Tags

For less motivated typists an even shorter delimiter syntax is available. Known as short-tags, this syntax forgoes the php reference required in the default syntax. However, to use this feature, you need to enable PHP’s short_open_tag directive. An example follows:

<?
print "This is another PHP example.";
?>

■Caution Although short-tag delimiters are convenient, keep in mind that they clash with XML, and thus XHTML,
syntax. Therefore, for conformance reasons you shouldn’t use short-tag syntax.

When short-tags syntax is enabled and you want to quickly escape to and from PHP to output a bit of dynamic text, you can omit these statements using an output variation known as short-circuit syntax:

<?="This is another PHP example.";?>

This is functionally equivalent to both of the following variations:

<? echo "This is another PHP example."; ?>
<?php echo "This is another PHP example.";?>

Script

Historically, certain editors, Microsoft’s FrontPage editor in particular, have had problems dealing with escape syntax such as that employed by PHP. Therefore, support for another mainstream delimiter variant, <script>, is offered:

<script language="php">
print "This is another PHP example.";
</script>

■Tip Microsoft’s FrontPage editor also recognizes ASP-style delimiter syntax, introduced next.

ASP Style

Microsoft ASP pages employ a similar strategy, delimiting static from dynamic syntax by using a predefined character pattern, opening dynamic syntax with <%, and concluding with %>. If you’re coming from an ASP background and prefer to continue using this escape syntax, PHP supports it. Here’s an example:

<%
print "This is another PHP example.";
%>

■Caution ASP-style syntax was removed as of PHP 6.

Embedding Multiple Code Blocks

You can escape to and from PHP as many times as required within a given page. For instance, the following example is perfectly acceptable:
<html>
<head>
<title><?php echo "Welcome to my Web site!";?></title>
</head>
<body>
<?php
$date = "July 26, 2007";
?>
<p>Today's date is <?=$date;?></p>
</body>
</html>

As you can see, any variables declared in a prior code block are “remembered” for later blocks, as is the case with the $date variable in this example.

Commenting Your Code

Whether for your own benefit or for that of a programmer later tasked with maintaining your code, the importance of thoroughly commenting your code cannot be overstated. PHP offers several syntactical variations, each of which is introduced in this section.

Single-Line C++ Syntax

Comments often require no more than a single line. Because of its brevity, there is no need to delimit the comment’s conclusion because the newline (\n) character fills this need quite nicely. PHP supports C++ single-line comment syntax, which is prefaced with a double slash (//), like this:

<?php
// Title: My first PHP script
// Author: Jason
echo "This is a PHP program";
?>

Shell Syntax

PHP also supports an alternative to the C++-style single-line syntax, known as shell syntax, which is prefaced with a hash mark (#). Revisiting the previous example, we use hash marks to add some information about the script:

<?php
# Title: My PHP program
# Author: Jason
echo "This is a PHP program";
?>

Multiple-Line C Syntax

It’s often convenient to include somewhat more verbose functional descriptions or other explana- tory notes within code, which logically warrants numerous lines. Although you could preface each line with C++ or shell-style delimiters, PHP also offers a multiple-line variant that can open and close the comment on different lines. Here’s an example:

<?php
/*
Title: My PHP Program
Author: Jason
Date: July 26, 2007
*/
?>

ADVANCED DOCUMENTATION WITH PHPDOCUMENTOR

Because documentation is such an important part of effective code creation and management, considerable effort has been put into devising methods for helping developers automate the process. In fact, these days documentation solutions are available for all mainstream programming languages, PHP included. phpDocumentor (http://www. phpdoc.org/) is an open source project that facilitates the documentation process by converting the comments embedded within the source code into a variety of easily readable formats, including HTML and PDF.
phpDocumentor works by parsing an application’s source code, searching for special comments known as DocBlocks. Used to document all code within an application, including scripts, classes, functions, variables, and more, DocBlocks contain human-readable explanations along with formalized descriptors such as the author’s name, code version, copyright statement, function return values, and much more.
Even if you’re a novice programmer, it’s strongly suggested you become familiar with advanced documentation solutions and get into the habit of using them for even basic applications.

Outputting Data to the Browser

Of course, even the simplest of Web sites will output data to the browser, and PHP offers several methods for doing so.

■Note Throughout this chapter, and indeed the rest of this book, when introducing functions we’ll refer to their
prototype. A prototype is simply the function’s definition, formalizing its name, input parameters, and the type of value it returns, defined by a datatype. If you don’t know what a datatype is, see the section “PHP’s Supported Datatypes” later in this chapter.

The print() Statement

The print() statement outputs data passed to it to the browser. Its prototype looks like this:

int print(argument)

All of the following are plausible print() statements:

<?php
print("<p>I love the summertime.</p>");
?>

<?php
$season = "summertime";
print "<p>I love the $season.</p>";
?>

<?php
print "<p>I love the summertime.</p>";
?>

All these statements produce identical output:

I love the summertime.

■Note Although the official syntax calls for the use of parentheses to enclose the argument, they’re not required.
Many programmers tend to forgo them simply because the target argument is equally apparent without them.

Alternatively, you could use the echo() statement for the same purposes as print(). While there are technical differences between echo() and print(), they’ll be irrelevant to most readers and there- fore aren’t discussed here. echo()’s prototype looks like this:

void echo(string argument1 [, ...string argumentN])

As you can see from the prototype, echo() is capable of outputting multiple strings. The utility of this particular trait is questionable; using it seems to be a matter of preference more than anything else. Nonetheless, it’s available should you feel the need. Here’s an example:
<?php
$heavyweight = "Lennox Lewis";
$lightweight = "Floyd Mayweather";
echo $heavyweight, " and ", $lightweight, " are great fighters.";
?>

This code produces the following:

Lennox Lewis and Floyd Mayweather are great fighters.

If your intent is to output a blend of static text and dynamic information passed through vari- ables, consider using printf() instead, which is introduced next. Otherwise, if you’d like to simply output static text, echo() or print() works great.

■Tip Which is faster, echo() or print()? The fact that they are functionally interchangeable leaves many
pondering this question. The answer is that the echo() function is a tad faster because it returns nothing, whereas print() will return 1 if the statement is successfully output. It’s rather unlikely that you’ll notice any speed differ- ence, however, so you can consider the usage decision to be one of stylistic concern.

The printf() Statement

The printf() statement is ideal when you want to output a blend of static text and dynamic informa- tion stored within one or several variables. It’s ideal for two reasons. First, it neatly separates the static and dynamic data into two distinct sections, allowing for easy maintenance. Second, printf() allows you to wield considerable control over how the dynamic information is rendered to the screen in terms of its type, precision, alignment, and position. Its prototype looks like this:

boolean printf(string format [, mixed args])

For example, suppose you wanted to insert a single dynamic integer value into an otherwise static string:

printf("Bar inventory: %d bottles of tonic water.", 100);

Executing this command produces the following:

Bar inventory: 100 bottles of tonic water.

In this example, %d is a placeholder known as a type specifier, and the d indicates an integer value will be placed in that position. When the printf() statement executes, the lone argument, 100, will be inserted into the placeholder. Remember that an integer is expected, so if you pass along a number including a decimal value (known as a float), it will be rounded down to the closest integer. If you pass along 100.2 or 100.6, 100 will be output. Pass along a string value such as "one hundred", and 0 will be output. Similar logic applies to other type specifiers (see Table 3-1 for a list of commonly used
specifiers).

Table 3-1. Commonly Used Type Specifiers

Type Description

%b Argument considered an integer; presented as a binary number

%c Argument considered an integer; presented as a character corresponding to that
ASCII value

%d Argument considered an integer; presented as a signed decimal number

%f Argument considered a floating-point number; presented as a floating-point number

%o Argument considered an integer; presented as an octal number

%s Argument considered a string; presented as a string

%u Argument considered an integer; presented as an unsigned decimal number

%x Argument considered an integer; presented as a lowercase hexadecimal number

%X Argument considered an integer; presented as an uppercase hexadecimal number

So what do you do if you want to pass along two values? Just insert two specifiers into the string and make sure you pass two values along as arguments. For example, the following printf() statement passes in an integer and float value:

printf("%d bottles of tonic water cost $%f", 100, 43.20);

Executing this command produces the following:

100 bottles of tonic water cost $43.20

When working with decimal values, you can adjust the precision using a precision specifier. An example follows:

printf("$%.2f", 43.2); // $43.20

Still other specifiers exist for tweaking the argument’s alignment, padding, sign, and width. Consult the PHP manual for more information.

The sprintf() Statement

The sprintf() statement is functionally identical to printf() except that the output is assigned to a string rather than rendered to the browser. The prototype follows:

string sprintf(string format [, mixed arguments])

An example follows:

$cost = sprintf("$%.2f", 43.2); // $cost = $43.20

PHP’s Supported Datatypes

A datatype is the generic name assigned to any data sharing a common set of characteristics. Common datatypes include Boolean, integer, float, string, and array. PHP has long offered a rich set of datatypes, and in this section you’ll learn about them.

Scalar Datatypes

Scalar datatypes are capable of containing a single item of information. Several datatypes fall under this category, including Boolean, integer, float, and string.

Boolean

The Boolean datatype is named after George Boole (1815–1864), a mathematician who is considered to be one of the founding fathers of information theory. A Boolean variable represents truth, supporting only two values: TRUE and FALSE (case insensitive). Alternatively, you can use zero to represent FALSE, and any nonzero value to represent TRUE. A few examples follow:

$alive = false; // $alive is false.
$alive = 1; // $alive is true.
$alive = -1; // $alive is true.
$alive = 5; // $alive is true.
$alive = 0; // $alive is false.

Integer

An integer is representative of any whole number or, in other words, a number that does not contain fractional parts. PHP supports integer values represented in base 10 (decimal), base 8 (octal), and base 16 (hexadecimal) numbering systems, although it’s likely you’ll only be concerned with the first of those systems. Several examples follow:

42 // decimal
-678900 // decimal
0755 // octal
0xC4E // hexadecimal

The maximum supported integer size is platform-dependent, although this is typically positive or negative 231 for PHP version 5 and earlier. PHP 6 introduced a 64-bit integer value, meaning PHP will support integer values up to positive or negative 263 in size.

Float

Floating-point numbers, also referred to as floats, doubles, or real numbers, allow you to specify numbers that contain fractional parts. Floats are used to represent monetary values, weights, distances, and a whole host of other representations in which a simple integer value won’t suffice. PHP’s floats can be specified in a variety of ways, each of which is exemplified here:

4.5678
4.0
8.7e4
1.23E+11

String

Simply put, a string is a sequence of characters treated as a contiguous group. Strings are delimited by single or double quotes, although PHP also supports another delimitation methodology, which is introduced in the later section “String Interpolation.”
The following are all examples of valid strings:

"PHP is a great language" "whoop-de-do"
'*9subway\n' "123$%^789"

Historically, PHP treated strings in the same fashion as arrays (see the next section, “Compound Datatypes,” for more information about arrays), allowing for specific characters to be accessed via array offset notation. For example, consider the following string:

$color = "maroon";

You could retrieve a particular character of the string by treating the string as an array, like this:

$parser = $color[2]; // Assigns 'r' to $parser

Compound Datatypes

Compound datatypes allow for multiple items of the same type to be aggregated under a single representative entity. The array and the object fall into this category.

Array

It’s often useful to aggregate a series of similar items together, arranging and referencing them in some specific way. This data structure, known as an array, is formally defined as an indexed collection of data values. Each member of the array index (also known as the key) references a corresponding value and can be a simple numerical reference to the value’s position in the series, or it could have some direct correlation to the value. For example, if you were interested in creating a list of U.S. states, you could use a numerically indexed array, like so:

$state[0] = "Alabama";
$state[1] = "Alaska";
$state[2] = "Arizona";
...
$state[49] = "Wyoming";

But what if the project required correlating U.S. states to their capitals? Rather than base the keys on a numerical index, you might instead use an associative index, like this:

$state["Alabama"] = "Montgomery";
$state["Alaska"] = "Juneau";
$state["Arizona"] = "Phoenix";
...
$state["Wyoming"] = "Cheyenne";
Arrays are formally introduced in Chapter 5, so don’t worry too much about the matter if you don’t completely understand these concepts right now.

■Note PHP also supports arrays consisting of several dimensions, better known as multidimensional arrays. This
concept is introduced in Chapter 5.

Object

The other compound datatype supported by PHP is the object. The object is a central concept of the object-oriented programming paradigm. If you’re new to object-oriented programming, Chapters 6 and 7 are devoted to the topic.
Unlike the other datatypes contained in the PHP language, an object must be explicitly declared.
This declaration of an object’s characteristics and behavior takes place within something called a
class. Here’s a general example of class definition and subsequent invocation:

class Appliance {
private $_power;
function setPower($status) {
$this->_power = $status;
}
}
...
$blender = new Appliance;

A class definition creates several attributes and functions pertinent to a data structure, in this case a data structure named Appliance. There is only one attribute, power, which can be modified by using the method setPower().
Remember, however, that a class definition is a template and cannot itself be manipulated. Instead, objects are created based on this template. This is accomplished via the new keyword. There- fore, in the last line of the previous listing, an object of class Appliance named blender is created.
The blender object’s power attribute can then be set by making use of the method setPower():

$blender->setPower("on");

Improvements to PHP’s object-oriented development model are a highlight of PHP 5 and are further enhanced in PHP 6. Chapters 6 and 7 are devoted to thorough coverage of PHP’s object- oriented development model.

Converting Between Datatypes Using Type Casting

Converting values from one datatype to another is known as type casting. A variable can be evaluated once as a different type by casting it to another. This is accomplished by placing the intended type in front of the variable to be cast. A type can be cast by inserting one of the operators shown in Table 3-2 in front of the variable.

Table 3-2. Type Casting Operators

Cast Operators Conversion

(array) Array (bool) or (boolean) Boolean (int) or (integer) Integer
(int64) 64-bit integer (introduced in PHP 6)
(object) Object (real) or (double) or (float) Float (string) String

Let’s consider several examples. Suppose you’d like to cast an integer as a double:

$score = (double) 13; // $score = 13.0

Type casting a double to an integer will result in the integer value being rounded down, regard- less of the decimal value. Here’s an example:

$score = (int) 14.8; // $score = 14

What happens if you cast a string datatype to that of an integer? Let’s find out:

$sentence = "This is a sentence";
echo (int) $sentence; // returns 0

In light of PHP’s loosely typed design, it will simply return the integer value unmodified. However, as you’ll see in the next section, PHP will sometimes take the initiative and cast a type to best fit the requirements of a given situation.
You can also cast a datatype to be a member of an array. The value being cast simply becomes the first element of the array:
$score = 1114;
$scoreboard = (array) $score;
echo $scoreboard[0]; // Outputs 1114

Note that this shouldn’t be considered standard practice for adding items to an array because this only seems to work for the very first member of a newly created array. If it is cast against an existing array, that array will be wiped out, leaving only the newly cast value in the first position. See Chapter 5 for more information about creating arrays.
One final example: any datatype can be cast as an object. The result is that the variable becomes an attribute of the object, the attribute having the name scalar:
$model = "Toyota";
$obj = (object) $model;

The value can then be referenced as follows:

print $ obj->scalar; // returns "Toyota"

Adapting Datatypes with Type Juggling

Because of PHP’s lax attitude toward type definitions, variables are sometimes automatically cast to best fit the circumstances in which they are referenced. Consider the following snippet:
<?php
$total = 5; // an integer
$count = "15"; // a string
$total += $count; // $total = 20 (an integer)
?>

The outcome is the expected one; $total is assigned 20, converting the $count variable from
a string to an integer in the process. Here’s another example demonstrating PHP’s type-juggling capabilities:
<?php
$total = "45 fire engines";
$incoming = 10;
$total = $incoming + $total; // $total = 55
?>

The integer value at the beginning of the original $total string is used in the calculation.
However, if it begins with anything other than a numerical representation, the value is 0. Consider another example:

<?php
$total = "1.0";
if ($total) echo "We're in positive territory!";
?>
In this example, a string is converted to Boolean type in order to evaluate the if statement. Consider one last particularly interesting example. If a string used in a mathematical calculation
includes ., e, or E (representing scientific notation), it will be evaluated as a float:

<?php
$val1 = "1.2e3"; // 1,200
$val2 = 2;
echo $val1 * $val2; // outputs 2400
?>

Type-Related Functions

A few functions are available for both verifying and converting datatypes; they are covered in this section.

Retrieving Types

The gettype() function returns the type of the variable specified by var. In total, eight possible return values are available: array, boolean, double, integer, object, resource, string, and unknown type. Its prototype follows:

string gettype (mixed var)

Converting Types

The settype() function converts a variable, specified by var, to the type specified by type. Seven possible type values are available: array, boolean, float, integer, null, object, and string. If the conversion is successful, TRUE is returned; otherwise, FALSE is returned. Its prototype follows:

boolean settype(mixed var, string type)

Type Identifier Functions

A number of functions are available for determining a variable’s type, including is_array(), is_bool(), is_float(), is_integer(), is_null(), is_numeric(), is_object(), is_resource(), is_scalar(), and is_string(). Because all of these functions follow the same naming convention, arguments, and return values, their introduction is consolidated into a single example. The generalized prototype follows:

boolean is_name(mixed var)

All of these functions are grouped in this section because each ultimately accomplishes the same task. Each determines whether a variable, specified by var, satisfies a particular condition specified by the function name. If var is indeed of the type tested by the function name, TRUE is returned; otherwise, FALSE is returned. An example follows:

<?php
$item = 43;
printf("The variable \$item is of type array: %d <br />", is_array($item)); printf("The variable \$item is of type integer: %d <br />", is_integer($item)); printf("The variable \$item is numeric: %d <br />", is_numeric($item));
?>

This code returns the following:

The variable $item is of type array: 0
The variable $item is of type integer: 1
The variable $item is numeric: 1

You might be wondering about the backslash preceding $item. Given the dollar sign’s special purpose of identifying a variable, there must be a way to tell the interpreter to treat it as a normal character should you want to output it to the screen. Delimiting the dollar sign with a backslash will accomplish this.

Identifiers

Identifier is a general term applied to variables, functions, and various other user-defined objects. There are several properties that PHP identifiers must abide by:

• An identifier can consist of one or more characters and must begin with a letter or an under- score. Furthermore, identifiers can consist of only letters, numbers, underscore characters, and other ASCII characters from 127 through 255. Table 3-3 shows a few examples of valid and invalid identifiers.

Table 3-3. Valid and Invalid Identifiers

Valid Invalid

my_function This&that

Size !counter

_someword 4ward

• Identifiers are case sensitive. Therefore, a variable named $recipe is different from a variable named $Recipe, $rEciPe, or $recipE.
• Identifiers can be any length. This is advantageous because it enables a programmer to accu- rately describe the identifier’s purpose via the identifier name.
• An identifier name can’t be identical to any of PHP’s predefined keywords. You can find a complete list of these keywords in the PHP manual appendix.

Variables

Although variables have been used in numerous examples in this chapter, the concept has yet to be formally introduced. This section does so, starting with a definition. Simply put, a variable is a symbol that can store different values at different times. For example, suppose you create a Web- based calculator capable of performing mathematical tasks. Of course, the user will want to plug in values of his choosing; therefore, the program must be able to dynamically store those values and perform calculations accordingly. At the same time, the programmer requires a user-friendly means for referring to these value-holders within the application. The variable accomplishes both tasks.
Given the importance of this programming concept, it would be wise to explicitly lay the
groundwork as to how variables are declared and manipulated. In this section, these rules are examined in detail.

■Note A variable is a named memory location that contains data and may be manipulated throughout the execu-
tion of the program.

Variable Declaration

A variable always begins with a dollar sign, $, which is then followed by the variable name. Variable names follow the same naming rules as identifiers. That is, a variable name can begin with either a letter or an underscore and can consist of letters, underscores, numbers, or other ASCII characters ranging from 127 through 255. The following are all valid variables:

• $color

• $operating_system

• $_some_variable

• $model

Note that variables are case sensitive. For instance, the following variables bear absolutely no relation to one another:

• $color

• $Color

• $COLOR

Interestingly, variables do not have to be explicitly declared in PHP as they do in Perl. Rather, variables can be declared and assigned values simultaneously. Nonetheless, just because you can do something doesn’t mean you should. Good programming practice dictates that all variables should be declared prior to use, preferably with an accompanying comment.
Once you’ve declared your variables, you can begin assigning values to them. Two methodologies are available for variable assignment: by value and by reference. Both are introduced next.

Value Assignment

Assignment by value simply involves copying the value of the assigned expression to the variable assignee. This is the most common type of assignment. A few examples follow:
$color = "red";
$number = 12;
$age = 12;
$sum = 12 + "15"; // $sum = 27

Keep in mind that each of these variables possesses a copy of the expression assigned to it. For example, $number and $age each possesses their own unique copy of the value 12. If you prefer that two variables point to the same copy of a value, you need to assign by reference, introduced next.

Reference Assignment

PHP 4 introduced the ability to assign variables by reference, which essentially means that you can create a variable that refers to the same content as another variable does. Therefore, a change to any variable referencing a particular item of variable content will be reflected among all other variables referencing that same content. You can assign variables by reference by appending an ampersand (&) to the equal sign. Let’s consider an example:

<?php
$value1 = "Hello";
$value2 =& $value1; // $value1 and $value2 both equal "Hello"
$value2 = "Goodbye"; // $value1 and $value2 both equal "Goodbye"
?>

An alternative reference-assignment syntax is also supported, which involves appending the
ampersand to the front of the variable being referenced. The following example adheres to this new syntax:

<?php
$value1 = "Hello";
$value2 = &$value1; // $value1 and $value2 both equal "Hello"
$value2 = "Goodbye"; // $value1 and $value2 both equal "Goodbye"
?>

References also play an important role in both function arguments and return values, as well as in object-oriented programming. Chapters 4 and 6 cover these features, respectively.

Variable Scope

However you declare your variables (by value or by reference), you can declare them anywhere in a PHP script. The location of the declaration greatly influences the realm in which a variable can be accessed, however. This accessibility domain is known as its scope.
PHP variables can be one of four scope types:

• Local variables

• Function parameters

• Global variables

• Static variables

Local Variables

A variable declared in a function is considered local. That is, it can be referenced only in that function. Any assignment outside of that function will be considered to be an entirely different variable from the one contained in the function. Note that when you exit the function in which a local variable has been declared, that variable and its corresponding value are destroyed.
Local variables are helpful because they eliminate the possibility of unexpected side effects, which can result from globally accessible variables that are modified, intentionally or not. Consider this listing:
$x = 4;
function assignx () {
$x = 0;
printf("\$x inside function is %d <br />", $x);
}
assignx();
printf("\$x outside of function is %d <br />", $x);

Executing this listing results in the following:

$x inside function is 0
$x outside of function is 4

As you can see, two different values for $x are output. This is because the $x located inside the assignx() function is local. Modifying the value of the local $x has no bearing on any values located outside of the function. On the same note, modifying the $x located outside of the function has no bearing on any variables contained in assignx().

Function Parameters

As in many other programming languages, in PHP, any function that accepts arguments must declare those arguments in the function header. Although those arguments accept values that come from outside of the function, they are no longer accessible once the function has exited.

■Note This section applies only to parameters passed by value and not to those passed by reference. Parameters passed by reference will indeed be affected by any changes made to the parameter from within the function. If you don’t know what this means, don’t worry about it because Chapter 4 addresses the topic in some detail.

Function parameters are declared after the function name and inside parentheses. They are declared much like a typical variable would be:
// multiply a value by 10 and return it to the caller function x10 ($value) {
$value = $value * 10;
return $value;
}

Keep in mind that although you can access and manipulate any function parameter in the func-
tion in which it is declared, it is destroyed when the function execution ends. You’ll learn more about functions in Chapter 4.

Global Variables

In contrast to local variables, a global variable can be accessed in any part of the program. To modify a global variable, however, it must be explicitly declared to be global in the function in which it is to be modified. This is accomplished, conveniently enough, by placing the keyword GLOBAL in front of the variable that should be recognized as global. Placing this keyword in front of an already existing variable tells PHP to use the variable having that name. Consider an example:

$somevar = 15;

function addit() { GLOBAL $somevar;
$somevar++;
echo "Somevar is $somevar";
}
addit();

The displayed value of $somevar would be 16. However, if you were to omit this line,

GLOBAL $somevar;

the variable $somevar would be assigned the value 1 because $somevar would then be considered local within the addit() function. This local declaration would be implicitly set to 0 and then incre- mented by 1 to display the value 1.
An alternative method for declaring a variable to be global is to use PHP’s $GLOBALS array. Recon- sidering the preceding example, you can use this array to declare the variable $somevar to be global:
$somevar = 15;

function addit() {
$GLOBALS["somevar"]++;
}

addit();
echo "Somevar is ".$GLOBALS["somevar"];

This returns the following:

Somevar is 16

Regardless of the method you choose to convert a variable to global scope, be aware that the global scope has long been a cause of grief among programmers due to unexpected results that may arise from its careless use. Therefore, although global variables can be extremely useful, be prudent when using them.

Static Variables

The final type of variable scoping to discuss is known as static. In contrast to the variables declared as function parameters, which are destroyed on the function’s exit, a static variable does not lose its value when the function exits and will still hold that value if the function is called again. You can declare a variable as static simply by placing the keyword STATIC in front of the variable name:

STATIC $somevar;

Consider an example:

function keep_track() { STATIC $count = 0;
$count++; echo $count; echo "<br />";
}

keep_track(); keep_track(); keep_track();
What would you expect the outcome of this script to be? If the variable $count was not designated to be static (thus making $count a local variable), the outcome would be as follows:

1
1
1

However, because $count is static, it retains its previous value each time the function is executed. Therefore, the outcome is the following:

1
2
3

Static scoping is particularly useful for recursive functions. Recursive functions are a powerful programming concept in which a function repeatedly calls itself until a particular condition is met. Recursive functions are covered in detail in Chapter 4.

PHP’s Superglobal Variables

PHP offers a number of useful predefined variables that are accessible from anywhere within the executing script and provide you with a substantial amount of environment-specific information.

You can sift through these variables to retrieve details about the current user session, the user’s operating environment, the local operating environment, and more. PHP creates some of the vari- ables, while the availability and value of many of the other variables are specific to the operating system and Web server. Therefore, rather than attempt to assemble a comprehensive list of all possible predefined variables and their possible values, the following code will output all predefined variables pertinent to any given Web server and the script’s execution environment:

foreach ($_SERVER as $var => $value) {
echo "$var => $value <br />";
}

This returns a list of variables similar to the following. Take a moment to peruse the listing
produced by this code as executed on a Windows server. You’ll see some of these variables again in the examples that follow:

HTTP_HOST => localhost:81
HTTP_USER_AGENT => Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US;
rv:1.8.0.10) Gecko/20070216 Firefox/1.5.0.10
HTTP_ACCEPT => text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain; q=0.8,image/png,*/*;q=0.5
HTTP_ACCEPT_LANGUAGE => en-us,en;q=0.5
HTTP_ACCEPT_ENCODING => gzip,deflate
HTTP_ACCEPT_CHARSET => ISO-8859-1,utf-8;q=0.7,*;q=0.7
HTTP_KEEP_ALIVE => 300
HTTP_CONNECTION => keep-alive PATH => C:\oraclexe\app\oracle\product\10.2.0\server\bin;c:\ruby\bin;C:\Windows\system32; C:\Windows;C:\Windows\System32\Wbem;C:\Program Files\QuickTime\QTSystem\;c:\php52\;c:\Python24
SystemRoot => C:\Windows
COMSPEC => C:\Windows\system32\cmd.exe
PATHEXT => .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.RB;.RBW WINDIR => C:\Windows
SERVER_SIGNATURE =>
Apache/2.0.59 (Win32) PHP/6.0.0-dev Server at localhost Port 81

SERVER_SOFTWARE => Apache/2.0.59 (Win32) PHP/6.0.0-dev
SERVER_NAME => localhost
SERVER_ADDR => 127.0.0.1
SERVER_PORT => 81
REMOTE_ADDR => 127.0.0.1
DOCUMENT_ROOT => C:/apache2/htdocs
SERVER_ADMIN => wj@wjgilmore.com
SCRIPT_FILENAME => C:/apache2/htdocs/books/php-oracle/3/server.php
REMOTE_PORT => 49638
GATEWAY_INTERFACE => CGI/1.1
SERVER_PROTOCOL => HTTP/1.1
REQUEST_METHOD => GET QUERY_STRING =>
REQUEST_URI => /books/php-oracle/3/server.php
SCRIPT_NAME => /books/php-oracle/3/server.php PHP_SELF => /books/php-oracle/3/server.php REQUEST_TIME => 1174440456

As you can see, quite a bit of information is available—some useful, some not so useful. You can display just one of these variables simply by treating it as a regular variable. For example, use this
to display the user’s IP address:

printf("Your IP address is: %s", $_SERVER['REMOTE_ADDR']);

This returns a numerical IP address, such as 192.0.34.166.
You can also gain information regarding the user’s browser and operating system. Consider the following one-liner:

printf("Your browser is: %s", $_SERVER['HTTP_USER_AGENT']);

This returns information similar to the following:

Your browser is: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US;
rv:1.8.0.10)Gecko/20070216 Firefox/1.5.0.10

This example illustrates only one of PHP’s nine predefined variable arrays. The rest of this section is devoted to introducing the purpose and contents of each.

■Note To use the predefined variable arrays, the configuration parameter track_vars must be enabled in the
php.ini file. As of PHP 4.03, track_vars is always enabled.

Learning More About the Server and Client

The $_SERVER superglobal contains information created by the Web server and offers a bevy of infor- mation regarding the server and client configuration and the current request environment. Although the value and number of variables found in $_SERVER varies by server, you can typically expect to find those defined in the CGI 1.1 specification (available at the National Center for Supercomputing Applications at http://hoohoo.ncsa.uiuc.edu/cgi/env.html). You’ll likely find all of these variables to be quite useful in your applications, some of which include the following:

$_SERVER['HTTP_REFERER']: The URL of the page that referred the user to the current location.

$_SERVER['REMOTE_ADDR']: The client’s IP address.

$_SERVER['REQUEST_URI']: The path component of the URL. For example, if the URL is http://
www.example.com/blog/apache/index.html, the URI is /blog/apache/index.html.

$_SERVER['HTTP_USER_AGENT']: The client’s user agent, which typically offers information about both the operating system and the browser.

Retrieving Variables Passed Using GET

The $_GET superglobal contains information pertinent to any parameters passed using the GET method. If the URL http://www.example.com/index.html?cat=apache&id=157 is requested, you could access the following variables by using the $_GET superglobal:
$_GET['cat'] = "apache"
$_GET['id'] = "157"

The $_GET superglobal by default is the only way that you can access variables passed via the GET method. You cannot reference GET variables like this: $cat, $id. See Chapter 21 for more about safely accessing external data.

Retrieving Variables Passed Using POST

The $_POST superglobal contains information pertinent to any parameters passed using the POST
method. Consider the following form, used to solicit subscriber information:

<form action="subscribe.php" method="post">
<p>
Email address:<br />
<input type="text" name="email" size="20" maxlength="50" value="" />
</p>
<p>
Password:<br />
<input type="password" name="pswd" size="20" maxlength="15" value="" />
</p>
<p>
<input type="submit" name="subscribe" value="subscribe!" />
</p>
</form>

The following POST variables will be made available via the target subscribe.php script:

$_POST['email'] = "jason@example.com";
$_POST['pswd'] = "rainyday";
$_POST['subscribe'] = "subscribe!";

Like $_GET, the $_POST superglobal is by default the only way to access POST variables. You cannot reference POST variables like this: $email, $pswd, and $subscribe.

Retrieving Information Stored Within Cookies

The $_COOKIE superglobal stores information passed into the script through HTTP cookies. Such cookies are typically set by a previously executed PHP script through the PHP function setcookie(). For example, suppose that you use setcookie() to store a cookie named example.com with the value ab2213. You could later retrieve that value by calling $_COOKIE["example.com"]. Chapter 18 introduces PHP’s cookie-handling capabilities.

Retrieving Information About Files Uploaded Using POST

The $_FILES superglobal contains information regarding data uploaded to the server via the POST method. This superglobal is a tad different from the others in that it is a two-dimensional array containing five elements. The first subscript refers to the name of the form’s file-upload form element; the second is one of five predefined subscripts that describe a particular attribute of the uploaded file:

$_FILES['upload-name']['name']: The name of the file as uploaded from the client to the server.

$_FILES['upload-name']['type']: The MIME type of the uploaded file. Whether this variable is assigned depends on the browser capabilities.

$_FILES['upload-name']['size']: The byte size of the uploaded file.

$_FILES['upload-name']['tmp_name']: Once uploaded, the file will be assigned a temporary name before it is moved to its final location.

$_FILES['upload-name']['error']: An upload status code. Despite the name, this variable will be populated even in the case of success. There are five possible values:

• UPLOAD_ERR_OK: The file was successfully uploaded.

• UPLOAD_ERR_INI_SIZE: The file size exceeds the maximum size imposed by the upload_max_
filesize directive.

• UPLOAD_ERR_FORM_SIZE: The file size exceeds the maximum size imposed by an optional
MAX_FILE_SIZE hidden form-field parameter.

• UPLOAD_ERR_PARTIAL: The file was only partially uploaded.

• UPLOAD_ERR_NO_FILE: A file was not specified in the upload form prompt. Chapter 15 is devoted to a complete introduction of PHP’s file-upload functionality.

Learning More About the Operating System Environment

The $_ENV superglobal offers information regarding the PHP parser’s underlying server environment. Some of the variables found in this array include the following:

$_ENV['HOSTNAME']: The server hostname

$_ENV['SHELL']: The system shell

■Caution PHP supports two other superglobals, namely $GLOBALS and $_REQUEST. The $_REQUEST super-
global is a catch-all of sorts, recording variables passed to a script via the GET, POST, and Cookie methods.
The order of these variables doesn’t depend on the order in which they appear in the sending script, but rather it depends on the order specified by the variables_order configuration directive. The $GLOBALS superglobal array can be thought of as the superglobal superset and contains a comprehensive listing of all variables found in the global scope. Although it may be tempting, you shouldn’t use these superglobals as a convenient way to handle variables because it is insecure. See Chapter 21 for an explanation.

Retrieving Information Stored in Sessions

The $_SESSION superglobal contains information regarding all session variables. Registering session information allows you the convenience of referring to it throughout your entire Web site, without the hassle of explicitly passing the data via GET or POST. Chapter 18 is devoted to PHP’s formidable session-handling feature.

Variable Variables

On occasion, you may want to use a variable whose content can be treated dynamically as a variable in itself. Consider this typical variable assignment:

$recipe = "spaghetti";

Interestingly, you can treat the value spaghetti as a variable by placing a second dollar sign in front of the original variable name and again assigning another value:

$$recipe = "& meatballs";

This in effect assigns & meatballs to a variable named spaghetti. Therefore, the following two snippets of code produce the same result:

echo $recipe $spaghetti;
echo $recipe ${$recipe};

The result of both is the string spaghetti & meatballs.

Constants

A constant is a value that cannot be modified throughout the execution of a program. Constants are particularly useful when working with values that definitely will not require modification, such as pi (3.141592) or the number of feet in a mile (5,280). Once a constant has been defined, it cannot be changed (or redefined) at any other point of the program. Constants are defined using the define() function.

Defining a Constant

The define() function defines a constant by assigning a value to a name. Its prototype follows:

boolean define(string name, mixed value [, bool case_insensitive])

If the optional parameter case_insensitive is included and assigned TRUE, subsequent references to the constant will be case insensitive. Consider the following example in which the mathematical constant PI is defined:

define("PI", 3.141592);

The constant is subsequently used in the following listing:

printf("The value of pi is %f", PI);
$pi2 = 2 * PI;
printf("Pi doubled equals %f", $pi2);

This code produces the following results:

The value of pi is 3.141592. Pi doubled equals 6.283184.

There are several points to note regarding the previous listing. The first is that constant references are not prefaced with a dollar sign. The second is that you can’t redefine or undefine the constant once it has been defined (e.g., 2*PI); if you need to produce a value based on the constant, the value must be stored in another variable. Finally, constants are global; they can be referenced anywhere in your script.

Expressions

An expression is a phrase representing a particular action in a program. All expressions consist of at least one operand and one or more operators. A few examples follow:

$a = 5; // assign integer value 5 to the variable $a
$a = "5"; // assign string value "5" to the variable $a
$sum = 50 + $some_int; // assign sum of 50 + $some_int to $sum
$wine = "Zinfandel"; // assign "Zinfandel" to the variable $wine
$inventory++; // increment the variable $inventory by 1

Operands

Operands are the inputs of an expression. You might already be familiar with the manipulation and use of operands not only through everyday mathematical calculations, but also through prior programming experience. Some examples of operands follow:

$a++; // $a is the operand
$sum = $val1 + val2; // $sum, $val1 and $val2 are operands

Operators

An operator is a symbol that specifies a particular action in an expression. Many operators may be familiar to you. Regardless, you should remember that PHP’s automatic type conversion will convert types based on the type of operator placed between the two operands, which is not always the case in other programming languages.
The precedence and associativity of operators are significant characteristics of a programming language. Both concepts are introduced in this section. Table 3-4 contains a complete listing of all operators, ordered from highest to lowest precedence.

Table 3-4. Operator Precedence, Associativity, and Purpose

Operator Associativity Purpose

new NA Object instantiation

( ) NA Expression subgrouping

[ ] Right Index enclosure

! ~ ++ -- Right Boolean NOT, bitwise NOT, increment, decrement

@ Right Error suppression

/ * % Left Division, multiplication, modulus

+ - . Left Addition, subtraction, concatenation

<< >> Left Shift left, shift right (bitwise)

< <= > >= NA Less than, less than or equal to, greater than, greater than or equal to

== != === <> NA Is equal to, is not equal to, is identical to, is not equal to

& ^ | Left Bitwise AND, bitwise XOR, bitwise OR

&& || Left Boolean AND, Boolean OR

?: Right Ternary operator

= += *= /= .= %=&=
|= ^= <<= >>=

Right Assignment operators

AND XOR OR Left Boolean AND, Boolean XOR, Boolean OR

, Left Expression separation; example: $days =
array(1=>"Monday", 2=>"Tuesday")

Operator Precedence

Operator precedence is a characteristic of operators that determines the order in which they evaluate the operands surrounding them. PHP follows the standard precedence rules used in elementary school math class. Consider a few examples:

$total_cost = $cost + $cost * 0.06;

This is the same as writing

$total_cost = $cost + ($cost * 0.06);

because the multiplication operator has higher precedence than the addition operator.

Operator Associativity

The associativity characteristic of an operator specifies how operations of the same precedence (i.e., having the same precedence value, as displayed in Table 3-3) are evaluated as they are executed. Associativity can be performed in two directions, left to right or right to left. Left-to-right associativity means that the various operations making up the expression are evaluated from left to right. Consider the following example:

$value = 3 * 4 * 5 * 7 * 2;

The preceding example is the same as the following:

$value = ((((3 * 4) * 5) * 7) * 2);

This expression results in the value 840 because the multiplication (*) operator is left-to-right associative.
In contrast, right-to-left associativity evaluates operators of the same precedence from right to
left:

$c = 5;
print $value = $a = $b = $c;

The preceding example is the same as the following:

$c = 5;
$value = ($a = ($b = $c));

When this expression is evaluated, variables $value, $a, $b, and $c will all contain the value 5
because the assignment operator (=) has right-to-left associativity.

Arithmetic Operators

The arithmetic operators, listed in Table 3-5, perform various mathematical operations and will probably be used frequently in many of your PHP programs. Fortunately, they are easy to use.
Incidentally, PHP provides a vast assortment of predefined mathematical functions capable of performing base conversions and calculating logarithms, square roots, geometric values, and more. Check the manual for an updated list of these functions.

Table 3-5. Arithmetic Operators

Example Label Outcome
$a + $b Addition Sum of $a and $b
$a - $b Subtraction Difference of $a and $b
$a * $b Multiplication Product of $a and $b
$a / $b Division Quotient of $a and $b
$a % $b Modulus Remainder of $a divided by $b

Assignment Operators

The assignment operators assign a data value to a variable. The simplest form of assignment operator just assigns some value, while others (known as shortcut assignment operators) perform some other
operation before making the assignment. Table 3-6 lists examples using this type of operator.

Table 3-6. Assignment Operators

Example Label Outcome
$a = 5 Assignment $a equals 5
$a += 5 Addition-assignment $a equals $a plus 5
$a *= 5 Multiplication-assignment $a equals $a multiplied by 5
$a /= 5 Division-assignment $a equals $a divided by 5
$a .= 5 Concatenation-assignment $a equals $a concatenated with 5

String Operators

PHP’s string operators (see Table 3-7) provide a convenient way in which to concatenate strings together. There are two such operators, including the concatenation operator (.) and the concate- nation assignment operator (.=) discussed in the previous section.

■Note To concatenate means to combine two or more objects together to form one single entity.

Table 3-7. String Operators
Example Label Outcome
$a = "abc"."def"; Concatenation $a is assigned the string abcdef
$a .= "ghijkl"; Concatenation-assignment $a equals its current value concatenated with “ghijkl”

Here is an example involving string operators:

// $a contains the string value "Spaghetti & Meatballs";
$a = "Spaghetti" . "& Meatballs";

$a .= " are delicious."
// $a contains the value "Spaghetti & Meatballs are delicious."

The two concatenation operators are hardly the extent of PHP’s string-handling capabilities. Read Chapter 9 for a complete accounting of this important feature.

Increment and Decrement Operators
The increment (++) and decrement (--) operators listed in Table 3-8 present a minor convenience in terms of code clarity, providing shortened means by which you can add 1 to or subtract 1 from the current value of a variable.

Table 3-8. Increment and Decrement Operators

Example Label Outcome
++$a, $a++

--$a, $a-- Increment

Decrement Increment $a by 1

Decrement $a by 1

These operators can be placed on either side of a variable, and the side on which they are placed provides a slightly different effect. Consider the outcomes of the following examples:

$inv = 15; // Assign integer value 15 to $inv.
$oldInv = $inv--; // Assign $oldInv the value of $inv, then decrement $inv.
$origInv = ++$inv; // Increment $inv, then assign the new $inv value to $origInv.

As you can see, the order in which the increment and decrement operators are used has an impor- tant effect on the value of a variable. Prefixing the operand with one of these operators is known as a preincrement and predecrement operation, while postfixing the operand is known as a postincrement and postdecrement operation.

Logical Operators

Much like the arithmetic operators, logical operators (see Table 3-9) will probably play a major role in many of your PHP applications, providing a way to make decisions based on the values of multiple variables. Logical operators make it possible to direct the flow of a program and are used frequently with control structures, such as the if conditional and the while and for loops.
Logical operators are also commonly used to provide details about the outcome of other oper- ations, particularly those that return a value:

file_exists("filename.txt") OR echo "File does not exist!";

One of two outcomes will occur:

• The file filename.txt exists

• The sentence “File does not exist!” will be output

Table 3-9. Logical Operators

Example Label Outcome
$a && $b AND True if both $a and $b are true
$a AND $b AND True if both $a and $b are true
$a || $b OR True if either $a or $b is true
$a OR $b OR True if either $a or $b is true
!$a NOT True if $a is not true
NOT $a NOT True if $a is not true
$a XOR $b Exclusive OR True if only $a or only $b is true

Equality Operators

Equality operators (see Table 3-10) are used to compare two values, testing for equivalence.

Table 3-10. Equality Operators

Example Label Outcome
$a == $b Is equal to True if $a and $b are equivalent
$a != $b Is not equal to True if $a is not equal to $b
$a === $b Is identical to True if $a and $b are equivalent and $a and $b have the same type

It is a common mistake for even experienced programmers to attempt to test for equality using just one equal sign (e.g., $a = $b). Keep in mind that this will result in the assignment of the contents of $b to $a and will not produce the expected results.

Comparison Operators

Comparison operators (see Table 3-11), like logical operators, provide a method to direct program flow through an examination of the comparative values of two or more variables.

Table 3-11. Comparison Operators

Example Label Outcome
$a < $b Less than True if $a is less than $b
$a > $b Greater than True if $a is greater than $b
$a <= $b Less than or equal to True if $a is less than or equal to $b
$a >= $b Greater than or equal to True if $a is greater than or equal to $b
($a == 12) ? 5 : -1 Ternary If $a equals 12, return value is 5;
otherwise, return value is –1

Note that the comparison operators should be used only for comparing numerical values. Although you may be tempted to compare strings with these operators, you will most likely not arrive at the expected outcome if you do so. There is a substantial set of predefined functions that compare string values, which are discussed in detail in Chapter 9.

Bitwise Operators

Bitwise operators examine and manipulate integer values on the level of individual bits that make up the integer value (thus the name). To fully understand this concept, you need at least an introduc- tory knowledge of the binary representation of decimal integers. Table 3-12 presents a few decimal
integers and their corresponding binary representations.

Table 3-12. Binary Representations

Decimal Integer Binary Representation
2 10
5 101
10 1010
12 1100
145 10010001
1,452,012 101100010011111101100

The bitwise operators listed in Table 3-13 are variations on some of the logical operators but can result in drastically different outcomes.

Table 3-13. Bitwise Operators

Example Label Outcome
$a & $b AND And together each bit contained in $a and $b
$a | $b OR Or together each bit contained in $a and $b
$a ^ $b XOR Exclusive-or together each bit contained in $a and $b
~ $b NOT Negate each bit in $b
$a << $b Shift left $a will receive the value of $b shifted left two bits
$a >> $b Shift right $a will receive the value of $b shifted right two bits

If you are interested in learning more about binary encoding and bitwise operators and why they are important, check out Randall Hyde’s massive online reference, “The Art of Assembly Language Programming,” available at http://webster.cs.ucr.edu/.

String Interpolation

To offer developers the maximum flexibility when working with string values, PHP offers a means for both literal and figurative interpretation. For example, consider the following string:

The $animal jumped over the wall.\n

You might assume that $animal is a variable and that \n is a newline character, and therefore both should be interpreted accordingly. However, what if you want to output the string exactly as it is written, or perhaps you want the newline to be rendered but want the variable to display in its
literal form ($animal), or vice versa? All of these variations are possible in PHP, depending on how the strings are enclosed and whether certain key characters are escaped through a predefined sequence. These topics are the focus of this section.

Double Quotes

Strings enclosed in double quotes are the most commonly used in most PHP scripts because they offer the most flexibility. This is because both variables and escape sequences will be parsed accord- ingly. Consider the following example:
<?php
$sport = "boxing";
echo "Jason's favorite sport is $sport.";
?>

This example returns the following:

Jason's favorite sport is boxing.

Escape sequences are also parsed. Consider this example:

<?php
$output = "This is one line.\nAnd this is another line.";
echo $output;
?>

This returns the following within the browser source:

This is one line.
And this is another line.

It’s worth reiterating that this output is found in the browser source rather than in the browser window. Newline characters of this fashion are ignored by the browser window. However, if you view the source, you’ll see that the output in fact appears on two separate lines. The same idea holds true if the data were output to a text file.
In addition to the newline character, PHP recognizes a number of special escape sequences, all of which are listed in Table 3-14.

Table 3-14. Recognized Escape Sequences

Sequence Description

\n Newline character

\r Carriage return

\t Horizontal tab

\\ Backslash

\$ Dollar sign

\" Double quote

\[0-7]{1,3} Octal notation

\x[0-9A-Fa-f]{1,2} Hexadecimal notation

Single Quotes

Enclosing a string within single quotes is useful when the string should be interpreted exactly as stated. This means that both variables and escape sequences will not be interpreted when the string is parsed. For example, consider the following single-quoted string:

print 'This string will $print exactly as it\'s \n declared.';

This produces the following:

This string will $print exactly as it's \n declared.

Note that the single quote located in it's was escaped. Omitting the backslash escape character will result in a syntax error, unless the magic_quotes_gpc configuration directive is enabled. Consider another example:

print 'This is another string.\\';

This produces the following:

This is another string.\

In this example, the backslash appearing at the conclusion of the string has to be escaped; other- wise, the PHP parser would understand that the trailing single quote was to be escaped. However, if the backslash were to appear anywhere else within the string, there would be no need to escape it.

Heredoc

Heredoc syntax offers a convenient means for outputting large amounts of text. Rather than delimiting strings with double or single quotes, two identical identifiers are employed. An example follows:

<?php
$website = "http://www.romatermini.it";
echo <<<EXCERPT
<p>Rome's central train station, known as <a href = "$website">Roma Termini</a>, was built in 1867. Because it had fallen into severe disrepair in the late 20th century, the government knew that considerable resources were required to rehabilitate the station prior to the 50-year <i>Giubileo</i>.</p>
EXCERPT;
?>

Several points are worth noting regarding this example:

• The opening and closing identifiers, in the case of this example, EXCERPT, must be identical.
You can choose any identifier you please, but they must exactly match. The only constraint is that the identifier must consist of solely alphanumeric characters and underscores and must not begin with a digit or an underscore.
• The opening identifier must be preceded with three left-angle brackets, <<<.

• Heredoc syntax follows the same parsing rules as strings enclosed in double quotes. That is, both variables and escape sequences are parsed. The only difference is that double quotes do not need to be escaped.
• The closing identifier must begin at the very beginning of a line. It cannot be preceded with spaces or any other extraneous character. This is a commonly recurring point of confusion among users, so take special care to make sure your heredoc string conforms to this annoying requirement. Furthermore, the presence of any spaces following the opening or closing iden- tifier will produce a syntax error.

Heredoc syntax is particularly useful when you need to manipulate a substantial amount of material but do not want to put up with the hassle of escaping quotes.

Control Structures

Control structures determine the flow of code within an application, defining execution characteris- tics such as whether and how many times a particular code statement will execute, as well as when a code block will relinquish execution control. These structures also offer a simple means to intro- duce entirely new sections of code (via file-inclusion statements) into a currently executing script. In this section you’ll learn about all such control structures available to the PHP language.

Conditional Statements

Conditional statements make it possible for your computer program to respond accordingly to a wide variety of inputs, using logic to discern between various conditions based on input value. This functionality is so basic to the creation of computer software that it shouldn’t come as a surprise that a variety of conditional statements are a staple of all mainstream programming languages, PHP included.

The if Statement

The if statement is one of the most commonplace constructs of any mainstream programming language, offering a convenient means for conditional code execution. The following is the syntax:

if (expression) {
statement
}

As an example, suppose you want a congratulatory message displayed if the user guesses a
predetermined secret number:

<?php
$secretNumber = 453;
if ($_POST['guess'] == $secretNumber) {
echo "<p>Congratulations!</p>";
}
?>

The hopelessly lazy can forgo the use of brackets when the conditional body consists of only a
single statement. Here’s a revision of the previous example:

<?php
$secretNumber = 453;
if ($_POST['guess'] == $secretNumber) echo "<p>Congratulations!</p>";
?>

■Note Alternative enclosure syntax is available for the if, while, for, foreach, and switch control struc-
tures. This involves replacing the opening bracket with a colon (:) and replacing the closing bracket with endif;, endwhile;, endfor;, endforeach;, and endswitch;, respectively. There has been discussion regarding deprecating this syntax in a future release, although it is likely to remain valid for the foreseeable future.

The else Statement

The problem with the previous example is that output is only offered for the user who correctly guesses the secret number. All other users are left destitute, completely snubbed for reasons presumably linked to their lack of psychic power. What if you want to provide a tailored response no matter the outcome? To do so you would need a way to handle those not meeting the if conditional require- ments, a function handily offered by way of the else statement. Here’s a revision of the previous example, this time offering a response in both cases:
<?php
$secretNumber = 453;
if ($_POST['guess'] == $secretNumber) {
echo "<p>Congratulations!!</p>";
} else {
echo "<p>Sorry!</p>";
}
?>

Like if, the else statement brackets can be skipped if only a single code statement is enclosed.

The elseif Statement

The if-else combination works nicely in an “either-or” situation—that is, a situation in which only two possible outcomes are available. But what if several outcomes are possible? You would need a means for considering each possible outcome, which is accomplished with the elseif statement. Let’s revise the secret-number example again, this time offering a message if the user’s guess is rela- tively close (within ten) of the secret number:

<?php
$secretNumber = 453;
$_POST['guess'] = 442;
if ($_POST['guess'] == $secretNumber) {
echo "<p>Congratulations!</p>";
} elseif (abs ($_POST['guess'] - $secretNumber) < 10) {
echo "<p>You're getting close!</p>";
} else {
echo "<p>Sorry!</p>";
}
?>

Like all conditionals, elseif supports the elimination of bracketing when only a single state-
ment is enclosed.

The switch Statement

You can think of the switch statement as a variant of the if-else combination, often used when you need to compare a variable against a large number of values:

<?php
switch($category) {
case "news":
echo "<p>What's happening around the world</p>";
break;
case "weather":
echo "<p>Your weekly forecast</p>";
break;
case "sports":
echo "<p>Latest sports highlights</p>";
break;
default:
echo "<p>Welcome to my Web site</p>";
}
?>

Note the presence of the break statement at the conclusion of each case block. If a break state-
ment isn’t present, all subsequent case blocks will execute until a break statement is located. As an illustration of this behavior, let’s assume that the break statements are removed from the preceding example and that $category is set to weather. You’d get the following results:

Your weekly forecast Latest sports highlights Welcome to my Web site

Looping Statements

Although varied approaches exist, looping statements are a fixture in every widespread programming language. This isn’t a surprise because looping mechanisms offer a simple means for accomplishing a commonplace task in programming: repeating a sequence of instructions until a specific condition is satisfied. PHP offers several such mechanisms, none of which should come as a surprise if you’re familiar with other programming languages.

The while Statement

The while statement specifies a condition that must be met before execution of its embedded code is terminated. Its syntax is the following:

while (expression) {
statements
}

In the following example, $count is initialized to the value 1. The value of $count is then squared
and output. The $count variable is then incremented by 1, and the loop is repeated until the value of
$count reaches 5.

<?php
$count = 1;
while ($count < 5) {
printf("%d squared = %d <br />", $count, pow($count, 2));
$count++;
}
?>

The output looks like this:

1 squared = 1
2 squared = 4
3 squared = 9
4 squared = 16

Like all other control structures, multiple conditional expressions may also be embedded into the while statement. For instance, the following while block evaluates either until it reaches the end- of-file or until five lines have been read and output:

<?php
$linecount = 1;
$fh = fopen("sports.txt","r");
while (!feof($fh) && $linecount<=5) {
$line = fgets($fh, 4096);
echo $line. "<br />";
$linecount++;
}
?>

Given these conditionals, a maximum of five lines will be output from the sports.txt file,
regardless of its size.

The do...while Statement

The do...while looping statement is a variant of while but it verifies the loop conditional at the conclusion of the block rather than at the beginning. The following is its syntax:

do {
statements
} while (expression);

Both while and do...while are similar in function. The only real difference is that the code embedded within a while statement possibly could never be executed, whereas the code embedded within a do...while statement will always execute at least once. Consider the following example:

<?php
$count = 11;
do {
printf("%d squared = %d <br />", $count, pow($count, 2));
} while ($count < 10);
?>

The following is the outcome:

11 squared = 121

Despite the fact that 11 is out of bounds of the while conditional, the embedded code will execute once because the conditional is not evaluated until the conclusion.

The for Statement

The for statement offers a somewhat more complex looping mechanism than does while. The following is its syntax:

for (expression1; expression2; expression3) {
statements
}

There are a few rules to keep in mind when using PHP’s for loops:

• The first expression, expression1, is evaluated by default at the first iteration of the loop.

• The second expression, expression2, is evaluated at the beginning of each iteration. This expression determines whether looping will continue.
• The third expression, expression3, is evaluated at the conclusion of each loop.

• Any of the expressions can be empty, their purpose substituted by logic embedded within the
for block.

With these rules in mind, consider the following examples, all of which display a partial kilometer/
mile equivalency chart:

// Example One
for ($kilometers = 1; $kilometers <= 5; $kilometers++) {
printf("%d kilometers = %f miles <br />", $kilometers, $kilometers*0.62140);
}

// Example Two
for ($kilometers = 1; ; $kilometers++) {
if ($kilometers > 5) break;
printf("%d kilometers = %f miles <br />", $kilometers, $kilometers*0.62140);
}

// Example Three
$kilometers = 1;
for (;;) {
// if $kilometers > 5 break out of the for loop. if ($kilometers > 5) break;
printf("%d kilometers = %f miles <br />", $kilometers, $kilometers*0.62140);
$kilometers++;
}

The results for all three examples follow:

1 kilometers = 0.6214 miles
2 kilometers = 1.2428 miles
3 kilometers = 1.8642 miles
4 kilometers = 2.4856 miles
5 kilometers = 3.107 miles

The foreach Statement

The foreach looping construct syntax is adept at looping through arrays, pulling each key/value pair from the array until all items have been retrieved or some other internal conditional has been met. Two syntax variations are available, each of which is presented with an example.
The first syntax variant strips each value from the array, moving the pointer closer to the end with each iteration. The following is its syntax:

foreach (array_expr as $value) {
statement
}

Consider this example. Suppose you want to output an array of links:

<?php
$links = array("www.apress.com","www.php.net","www.apache.org");
echo "<b>Online Resources</b>:<br />";
foreach($links as $link) {
echo "<a href=\"http://$link\">$link</a><br />";
}
?>

This would result in the following:

Online Resources:<br />
<a href="http://www.apress.com">http://www.apress.com</a><br />
<a href="http://www.php.net">http://www.php.net</a><br />
<a href="http://www.apache.org"> http://www.apache.org </a><br />

The second variation is well-suited for working with both the key and value of an array. The syntax follows:

foreach (array_expr as $key => $value) {
statement
}

Revising the previous example, suppose that the $links array contains both a link and a corre-
sponding link title:

$links = array("The Apache Web Server" => "www.apache.org", "Apress" => "www.apress.com",
"The PHP Scripting Language" => "www.php.net");

Each array item consists of both a key and a corresponding value. The foreach statement can easily peel each key/value pair from the array, like this:

echo "<b>Online Resources</b>:<br />";
foreach($links as $title => $link) {
echo "<a href=\"http://$link\">$title</a><br />";
}

The result would be that each link is embedded under its respective title, like this:

Online Resources:<br />
<a href="http://www.apache.org">The Apache Web Server </a><br />
<a href="http://www.apress.com"> Apress </a><br />
<a href="http://www.php.net">The PHP Scripting Language </a><br />

There are other variations on this method of key/value retrieval, all of which are introduced in
Chapter 5.

The break and goto Statements

Encountering a break statement will immediately end execution of a do...while, for, foreach, switch, or while block. For example, the following for loop will terminate if a prime number is pseudo-randomly happened upon:

<?php
$primes = array(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47);
for($count = 1; $count++; $count < 1000) {
$randomNumber = rand(1,50);
if (in_array($randomNumber,$primes)) {
break;
} else {
printf("Non-prime number found: %d <br />", $randomNumber);
}
}
?>

Sample output follows:

Non-prime number found: 48
Non-prime number found: 42
Prime number found: 17

Through the addition of the goto statement, this feature was extended in PHP 6 to support labels. This means you can suddenly jump to a specific location outside of a looping or conditional construct. An example follows:

<?php
for ($count = 0; $count < 10; $count++)
{
$randomNumber = rand(1,50);

if ($randomNumber < 10)
goto less;

else

}

echo "Number greater than 10: $randomNumber<br />";

less:
echo "Number less than 10: $randomNumber<br />";
?>

It produces the following (your output will vary):

Number greater than 10: 22
Number greater than 10: 21
Number greater than 10: 35
Number less than 10: 8

The continue Statement

The continue statement causes execution of the current loop iteration to end and commence at the beginning of the next iteration. For example, execution of the following while body will recommence if $usernames[$x] is found to have the value missing:

<?php
$usernames = array("grace","doris","gary","nate","missing","tom");
for ($x=0; $x < count($usernames); $x++) {
if ($usernames[$x] == "missing") continue;
printf("Staff member: %s <br />", $usernames[$x]);
}
?>

This results in the following output:

Staff member: grace Staff member: doris Staff member: gary Staff member: nate Staff member: tom

File Inclusion Statements

Efficient programmers are always thinking in terms of ensuring reusability and modularity. The most prevalent means for ensuring such is by isolating functional components into separate files and then reassembling those files as needed. PHP offers four statements for including such files into applications, each of which is introduced in this section.

The include() Statement

The include() statement will evaluate and include a file into the location where it is called. Including a file produces the same result as copying the data from the file specified into the location in which the statement appears. Its prototype follows:

include(/path/to/filename)

Like the print and echo statements, you have the option of omitting the parentheses when using include(). For example, if you want to include a series of predefined functions and configuration variables, you could place them into a separate file (called init.inc.php, for example), and then include that file within the top of each PHP script, like this:

<?php
include "/usr/local/lib/php/wjgilmore/init.inc.php";
/* the script continues here */
?>

You can also execute include() statements conditionally. For example, if an include() state-
ment is placed in an if statement, the file will be included only if the if statement in which it is enclosed evaluates to true. One quirk regarding the use of include() in a conditional is that it must be enclosed in statement block curly brackets or in the alternative statement enclosure. Consider the difference in syntax between the following two code snippets. The first presents incorrect use of conditional include() statements due to the lack of proper block enclosures:

<?php
if (expression)
include ('filename');

else

?>

include ('another_filename');

The next snippet presents the correct use of conditional include() statements by properly enclosing the blocks in curly brackets:

<?php
if (expression) {
include ('filename');
} else {
include ('another_filename');
}
?>

One misconception about the include() statement is the belief that because the included code
will be embedded in a PHP execution block, the PHP escape tags aren’t required. However, this is not so; the delimiters must always be included. Therefore, you could not just place a PHP command in a file and expect it to parse correctly, such as the one found here:

echo "this is an invalid include file";

Instead, any PHP statements must be enclosed with the correct escape tags, as shown here:

<?php
echo "this is an invalid include file";
?>

■Tip Any code found within an included file will inherit the variable scope of the location of its caller.

Interestingly, all include() statements support the inclusion of files residing on remote servers by prefacing include()’s argument with a supported URL. If the resident server is PHP-enabled, any variables found within the included file can be parsed by passing the necessary key/value pairs as would be done in a GET request, like this:

include "http://www.wjgilmore.com/index.html?background=blue";

Two requirements must be satisfied before the inclusion of remote files is possible. First, the allow_url_fopen configuration directive must be enabled. Second, the URL wrapper must be supported. The latter requirement is discussed in further detail in Chapter 16.

Ensuring a File Is Included Only Once

The include_once() function has the same purpose as include() except that it first verifies whether the file has already been included. Its prototype follows:

include_once (filename)

If a file has already been included, include_once() will not execute. Otherwise, it will include the file as necessary. Other than this difference, include_once() operates in exactly the same way as include().
The same quirk pertinent to enclosing include() within conditional statements also applies to
include_once().

Requiring a File

For the most part, require() operates like include(), including a template into the file in which the
require() call is located. Its prototype follows:

require (filename)

However, there are two important differences between require() and include(). First, the file will be included in the script in which the require() construct appears, regardless of where require() is located. For instance, if require() is placed within an if statement that evaluates to false, the file
would be included anyway.

■Tip A URL can be used with require() only if allow_url_fopen is enabled, which by default it is.

The second important difference is that script execution will stop if a require() fails, whereas it may continue in the case of an include(). One possible explanation for the failure of a require() statement is an incorrectly referenced target path.

Ensuring a File Is Required Only Once

As your site grows, you may find yourself redundantly including certain files. Although this might not always be a problem, sometimes you will not want modified variables in the included file to be overwritten by a later inclusion of the same file. Another problem that arises is the clashing of function names should they exist in the inclusion file. You can solve these problems with the require_once() function. Its prototype follows:

require_once (filename)

The require_once() function ensures that the inclusion file is included only once in your script. After require_once() is encountered, any subsequent attempts to include the same file will be ignored.
Other than the verification procedure of require_once(), all other aspects of the function are the same as for require().

Summary

Although the material presented here is not as glamorous as the material in later chapters, it is invaluable to your success as a PHP programmer because all subsequent functionality is based on these building blocks. This will soon become apparent.
The next chapter is devoted to the construction and invocation of functions, reusable chunks of code intended to perform a specific task. This material starts you down the path necessary to begin building modular, reusable PHP applications.

0 comments: