Sunday, May 24, 2009

Expressions and Operators

Expressions and Operators

An expression is a bit of PHP that can be evaluated to produce a value. The simplest expressions are literal values and variables. A literal value evaluates to itself, while a variable evaluates to the value stored in the variable. More complex expressions can be formed using simple expressions and operators.

An operator takes some values (the operands) and does something (for instance, adds them together). Operators are written as punctuation symbols—for instance, the + and - familiar to us from math. Some operators modify their operands, while most do not.

Table 2-3 summarizes the operators in PHP, many of which were borrowed from C and Perl. The column labeled "P" gives the operator's precedence; the operators are listed in precedence order, from highest to lowest. The column labeled "A" gives the operator's associativity, which can be L (left-to-right), R (right-to-left), or N (non-associative).

Table 2-3. PHP operators

P

A

Operator

Operation

19

N

new

Create new object

18

R

[

Array subscript

17

R

!

Logical NOT

R

~

Bitwise NOT

R

++

Increment

R

--

Decrement

R

(int), (double), (string), (array), (object)

Cast

R

@

Inhibit errors

16

L

*

Multiplication

L

/

Division

L

%

Modulus

15

L

+

Addition

L

-

Subtraction

L

.

String concatenation

14

L

<<

Bitwise shift left

L

>>

Bitwise shift right

13

N

<, <=

Less than, less than or equal

N

>, >=

Greater than, greater than or equal

12

N

==

Value equality

N

!=, <>

Inequality

N

===

Type and value equality

N

!==

Type and value inequality

11

L

&

Bitwise AND

10

L

^

Bitwise XOR

9

L

|

Bitwise OR

8

L

&&

Logical AND

7

L

||

Logical OR

6

L

?:

Conditional operator

5

L

=

Assignment

L

+=, -=, *=, /=, .=, %=, &=, |=, ^=, ~=, <<=, >>=

Assignment with operation

4

L

and

Logical AND

3

L

xor

Logical XOR

2

L

or

Logical OR

1

L

,

List separator

Number of Operands

Most operators in PHP are binary operators; they combine two operands (or expressions) into a single, more complex expression. PHP also supports a number of unary operators, which convert a single expression into a more complex expression. Finally, PHP supports a single ternary operator that combines three expressions into a single expression.

Operator Precedence
The order in which operators in an expression are evaluated depends on their relative precedence. For example, you might write:

2 + 4 * 3
As you can see in Table 2-3, the addition and multiplication operators have different precedence, with multiplication higher than addition. So the multiplication happens before the addition, giving 2 + 12, or 14, as the answer. If the precedence of addition and multiplication were reversed, 6 * 3, or 18, would be the answer.

To force a particular order, you can group operands with the appropriate operator in parentheses. In our previous example, to get the value 18, you can use this expression:

(2 + 4) * 3
It is possible to write all complex expressions (expressions containing more than a single operator) simply by putting the operands and operators in the appropriate order so that their relative precedence yields the answer you want. Most programmers, however, write the operators in the order that they feel makes the most sense to programmers, and add parentheses to ensure it makes sense to PHP as well. Getting precedence wrong leads to code like:

$x + 2 / $y >= 4 ? $z : $x << $z
This code is hard to read and is almost definitely not doing what the programmer expected it to do.

One way many programmers deal with the complex precedence rules in programming languages is to reduce precedence down to two rules:

Multiplication and division have higher precedence than addition and subtraction.

Use parentheses for anything else.

Operator Associativity
Associativity defines the order in which operators with the same order of precedence are evaluated. For example, look at:

2 / 2 * 2
The division and multiplication operators have the same precedence, but the result of the expression depends on which operation we do first:

2/(2*2) // 0.5
(2/2)*2 // 2
The division and multiplication operators are left-associative; this means that in cases of ambiguity, the operators are evaluated from left to right. In this example, the correct result is 2.

Implicit Casting
Many operators have expectations of their operands—for instance, binary math operators typically require both operands to be of the same type. PHP's variables can store integers, floating-point numbers, strings, and more, and to keep as much of the type details away from the programmer as possible, PHP converts values from one type to another as necessary.

The conversion of a value from one type to another is called casting. This kind of implicit casting is called type juggling in PHP. The rules for the type juggling done by arithmetic operators are shown in Table 2-4.

Table 2-4. Implicit casting rules for binary arithmetic operations

Type of first operand

Type of second operand

Conversion performed

Integer

Floating point

The integer is converted to a floating-point number

Integer

String

The string is converted to a number; if the value after conversion is a floating-point number, the integer is converted to a floating-point number

Floating point

String

The string is converted to a floating-point number

Some other operators have different expectations of their operands, and thus have different rules. For example, the string concatenation operator converts both operands to strings before concatenating them:

3 . 2.74 // gives the string 32.74
You can use a string anywhere PHP expects a number. The string is presumed to start with an integer or floating-point number. If no number is found at the start of the string, the numeric value of that string is 0. If the string contains a period (.) or upper- or lowercase e, evaluating it numerically produces a floating-point number. For example:

"9 Lives" - 1; // 8 (int)
"3.14 Pies" * 2; // 6.28 (float)
"9 Lives." - 1; // 8 (float)
"1E3 Points of Light" + 1; // 1001 (float)
2.4.5 Arithmetic Operators
The arithmetic operators are operators you'll recognize from everyday use. Most of the arithmetic operators are binary; however, the arithmetic negation and arithmetic assertion operators are unary. These operators require numeric values, and non-numeric values are converted into numeric values by the rules described in Section 2.4.11. The arithmetic operators are:

Addition (+)
The result of the addition operator is the sum of the two operands.

Subtraction (-)
The result of the subtraction operator is the difference between the two operands; i.e., the value of the second operand subtracted from the first.

Multiplication (*)
The result of the multiplication operator is the product of the two operands. For example, 3 * 4 is 12.

Division (/)
The result of the division operator is the quotient of the two operands. Dividing two integers can give an integer (e.g., 4/2) or a floating-point result (e.g., 1/2).

Modulus (%)
The modulus operator converts both operands to integers and returns the remainder of the division of the first operand by the second operand. For example, 10 % 6 is 4.

Arithmetic negation (-)
The arithmetic negation operator returns the operand multiplied by -1, effectively changing its sign. For example, -(3 - 4) evaluates to 1. Arithmetic negation is different from the subtraction operator, even though they both are written as a minus sign. Arithmetic negation is always unary and before the operand. Subtraction is binary and between its operands.

Arithmetic assertion (+)
The arithmetic assertion operator returns the operand multiplied by +1, which has no effect. It is used only as a visual cue to indicate the sign of a value. For example, +(3 - 4) evaluates to -1, just as (3 - 4) does.

String Concatenation Operator
Manipulating strings is such a core part of PHP applications that PHP has a separate string concatenation operator (.). The concatenation operator appends the righthand operand to the lefthand operand and returns the resulting string. Operands are first converted to strings, if necessary. For example:

$n = 5;
$s = 'There were ' . $n . ' ducks.';
// $s is 'There were 5 ducks'
Autoincrement and Autodecrement Operators
In programming, one of the most common operations is to increase or decrease the value of a variable by one. The unary autoincrement (++) and autodecrement (--) operators provide shortcuts for these common operations. These operators are unique in that they work only on variables; the operators change their operands' values as well as returning a value.

There are two ways to use autoincrement or autodecrement in expressions. If you put the operator in front of the operand, it returns the new value of the operand (incremented or decremented). If you put the operator after the operand, it returns the original value of the operand (before the increment or decrement). Table 2-5 lists the different operations.

Table 2-5. Autoincrement and autodecrement operations

Operator

Name

Value returned

Effect on $var

$var++

Post-increment

$var

Incremented

++$var

Pre-increment

$var + 1

Incremented

$var--

Post-decrement

$var

Decremented

--$var

Pre-decrement

$var - 1

Decremented

These operators can be applied to strings as well as numbers. Incrementing an alphabetic character turns it into the next letter in the alphabet. As illustrated in Table 2-6, incrementing "z" or "Z" wraps it back to "a" or "Z" and increments the previous character by one, as though the characters were in a base-26 number system.

Table 2-6. Autoincrement with letters

Incrementing this

Gives this

"a"
"b"
"z"
"aa"
"spaz"
"spba"
"K9"
"L0"
"42"
"43"

Comparison Operators

As their name suggests, comparison operators compare operands. The result is always either true, if the comparison is truthful, or false, otherwise.

Operands to the comparison operators can be both numeric, both string, or one numeric and one string. The operators check for truthfulness in slightly different ways based on the types and values of the operands, either using strictly numeric comparisons or using lexicographic (textual) comparisons. Table 2-7 outlines when each type of check is used.

Table 2-7. Type of comparision performed by the comparision operators

First operand

Second operand

Comparison

Number

Number

Numeric

String that is entirely numeric

String that is entirely numeric

Numeric

String that is entirely numeric

Number

Numeric

String that is not entirely numeric

Number

Lexicographic

String that is entirely numeric

String that is not entirely numeric

Lexicographic

String that is not entirely numeric

String that is not entirely numeric

Lexicographic

One important thing to note is that two numeric strings are compared as if they were numbers. If you have two strings that consist entirely of numeric characters and you need to compare them lexicographically, use the strcmp( ) function.

The comparison operators are:

Equality (==)
If both operands are equal, this operator returns true; otherwise, it returns false.

Identical (===)
If both operands are equal and are of the same type, this operator returns true; otherwise, it returns false. Note that this operator does not do implicit type casting. This operator is useful when you don't know if the values you're comparing are of the same type. Simple comparison may involve value conversion. For instance, the strings "0.0" and "0" are not equal. The == operator says they are, but === says they are not.

Inequality (!= or <>)
If both operands are not equal, this operator returns true; otherwise, it returns false.

Not identical (!==)
If both operands are not equal, or they are not of the same type, this operator returns true; otherwise, it returns false.

Greater than (>)
If the lefthand operator is greater than the righthand operator, this operator returns true; otherwise, it returns false.

Greater than or equal to (>=)
If the lefthand operator is greater than or equal to the righthand operator, this operator returns true; otherwise, it returns false.

Less than (<)
If the lefthand operator is less than the righthand operator, this operator returns true; otherwise, it returns false.

Less than or equal to (<=)
If the lefthand operator is less than or equal to the righthand operator, this operator returns true; otherwise, it returns false.

Bitwise Operators
The bitwise operators act on the binary representation of their operands. Each operand is first turned into a binary representation of the value, as described in the bitwise negation operator entry in the following list. All the bitwise operators work on numbers as well as strings, but they vary in their treatment of string operands of different lengths. The bitwise operators are:

Bitwise negation (~)
The bitwise negation operator changes 1s to 0s and 0s to 1s in the binary representations of the operands. Floating-point values are converted to integers before the operation takes place. If the operand is a string, the resulting value is a string the same length as the original, with each character in the string negated.

Bitwise AND (&)
The bitwise AND operator compares each corresponding bit in the binary representations of the operands. If both bits are 1, the corresponding bit in the result is 1; otherwise, the corresponding bit is 0. For example, 0755 & 0671 is 0651. This is a bit easier to understand if we look at the binary representation. Octal 0755 is binary 111101101, and octal 0671 is binary 110111001. We can the easily see which bits are on in both numbers and visually come up with the answer:

111101101
& 110111001
---------
110101001
The binary number 110101001 is octal 0651.[2] You can use the PHP functions bindec( ), decbin( ), octdec( ), and decoct( ) to convert numbers back and forth when you are trying to understand binary arithmetic.

[2] Here's a tip: split the binary number up into three groups. 6 is binary 110, 5 is binary 101, and 1 is binary 001; thus, 0651 is 110101001.

If both operands are strings, the operator returns a string in which each character is the result of a bitwise AND operation between the two corresponding characters in the operands. The resulting string is the length of the shorter of the two operands; trailing extra characters in the longer string are ignored. For example, "wolf" & "cat" is "cad".

Bitwise OR (|)
The bitwise OR operator compares each corresponding bit in the binary representations of the operands. If both bits are 0, the resulting bit is 0; otherwise, the resulting bit is 1. For example, 0755 | 020 is 0775.

If both operands are strings, the operator returns a string in which each character is the result of a bitwise OR operation between the two corresponding characters in the operands. The resulting string is the length of the longer of the two operands, and the shorter string is padded at the end with binary 0s. For example, "pussy" | "cat" is "suwsy".

Bitwise XOR (^)
The bitwise XOR operator compares each corresponding bit in the binary representation of the operands. If either of the bits in the pair, but not both, is 1, the resulting bit is 1; otherwise, the resulting bit is 0. For example, 0755 ^ 023 is 776.

If both operands are strings, this operator returns a string in which each character is the result of a bitwise XOR operation between the two corresponding characters in the operands. If the two strings are different lengths, the resulting string is the length of the shorter operand, and extra trailing characters in the longer string are ignored. For example, "big drink" ^ "AA" is "#(".

Left shift (<<)
The left shift operator shifts the bits in the binary representation of the lefthand operand left by the number of places given in the righthand operand. Both operands will be converted to integers if they aren't already. Shifting a binary number to the left inserts a 0 as the rightmost bit of the number and moves all other bits to the left one place. For example, 3 <<>

Note that each place to the left that a number is shifted results in a doubling of the number. The result of left shifting is multiplying the lefthand operand by 2 to the power of the righthand operand.

Right shift (>>)
The right shift operator shifts the bits in the binary representation of the lefthand operand right by the number of places given in the righthand operand. Both operands will be converted to integers if they aren't already. Shifting a binary number to the right inserts a 0 as the leftmost bit of the number and moves all other bits to the right one place. The rightmost bit is discarded. For example, 13 >> 1 (or binary 1101) shifted one place right results in 6 (binary 110).

Logical Operators
Logical operators provide ways for you to build complex logical expressions. Logical operators treat their operands as Boolean values and return a Boolean value. There are both punctuation and English versions of the operators (|| and or are the same operator). The logical operators are:

Logical AND (&&, and)
The result of the logical AND operation is true if and only if both operands are true; otherwise, it is false. If the value of the first operand is false, the logical AND operator knows that the resulting value must also be false, so the righthand operand is never evaluated. This process is called short-circuiting, and a common PHP idiom uses it to ensure that a piece of code is evaluated only if something is true. For example, you might connect to a database only if some flag is not false:

$result = $flag and mysql_connect( );
The && and and operators differ only in their precedence.

Logical OR (||, or)
The result of the logical OR operation is true if either operand is true; otherwise, the result is false. Like the logical AND operator, the logical OR operator is short-circuited. If the lefthand operator is true, the result of the operator must be true, so the righthand operator is never evaluated. A common PHP idiom uses this to trigger an error condition if something goes wrong. For example:

$result = fopen($filename) or exit( );
The || and or operators differ only in their precedence.

Logical XOR (xor)
The result of the logical XOR operation is true if either operand, but not both, is true; otherwise, it is false.

Logical negation (!)
The logical negation operator returns the Boolean value true if the operand evaluates to false, and false if the operand evaluates to true.

Casting Operators
Although PHP is a weakly typed language, there are occasions when it's useful to consider a value as a specific type. The casting operators, (int) , (float), (string), (bool), (array), and (object), allow you to force a value into a particular type. To use a casting operator, put the operator to the left of the operand. Table 2-8 lists the casting operators, synonymous operands, and the type to which the operator changes the value.

Table 2-8. PHP casting operators

Operator

Synonymous operators

Changes type to

(int)
(integer)

Integer

(float)
(real)

Floating point

(string)

String

(bool)
(boolean)

Boolean

(array)

Array

(object)

Object

Casting affects the way other operators interpret a value, rather than changing the value in a variable. For example, the code:

$a = "5";
$b = (int) $a;
assigns $b the integer value of $a; $a remains the string "5". To cast the value of the variable itself, you must assign the result of a cast back into the variable:

$a = "5"
$a = (int) $a; // now $a holds an integer
Not every cast is useful: casting an array to a numeric type gives 1, and casting an array to a string gives "Array" (seeing this in your output is a sure sign that you've printed a variable that contains an array).

Casting an object to an array builds an array of the properties, mapping property names to values:

class Person {
var $name = "Fred";
var $age = 35;
}
$o = new Person;
$a = (array) $o;
print_r($a);
Array
(
[name] => Fred
[age] => 35
)
You can cast an array to an object to build an object whose properties correspond to the array's keys and values. For example:

$a = array('name' => 'Fred', 'age' => 35, 'wife' => 'Wilma');
$o = (object) $a;
echo $o->name;
Fred
Keys that aren't valid identifiers, and thus are invalid property names, are inaccessible but are restored when the object is cast back to an array.

Assignment Operators
Assignment operators store or update values in variables. The autoincrement and autodecrement operators we saw earlier are highly specialized assignment operators—here we see the more general forms. The basic assignment operator is =, but we'll also see combinations of assignment and binary operations, such as += and &=.

Assignment
The basic assignment operator (=) assigns a value to a variable. The lefthand operand is always a variable. The righthand operand can be any expression—any simple literal, variable, or complex expression. The righthand operand's value is stored in the variable named by the lefthand operand.

Because all operators are required to return a value, the assignment operator returns the value assigned to the variable. For example, the expression $a = 5 not only assigns 5 to $a, but also behaves as the value 5 if used in a larger expression. Consider the following expressions:

$a = 5;
$b = 10;
$c = ($a = $b);
The expression $a = $b is evaluated first, because of the parentheses. Now, both $a and $b have the same value, 10. Finally, $c is assigned the result of the expression $a = $b, which is the value assigned to the lefthand operand (in this case, $a). When the full expression is done evaluating, all three variables contain the same value, 10.

Assignment with operation
In addition to the basic assignment operator, there are several assignment operators that are convenient shorthand. These operators consist of a binary operator followed directly by an equals sign, and their effect is the same as performing the operation with the operands, then assigning the resulting value to the lefthand operand. These assignment operators are:

Plus-equals (+=)
Adds the righthand operand to the value of the lefthand operand, then assigns the result to the lefthand operand. $a += 5 is the same as $a = $a + 5.

Minus-equals (-=)
Subtracts the righthand operand from the value of the lefthand operand, then assigns the result to the lefthand operand.

Divide-equals (/=)
Divides the value of the lefthand operand by the righthand operand, then assigns the result to the lefthand operand.

Multiply-equals (*=)
Multiplies the righthand operand with the value of the lefthand operand, then assigns the result to the lefthand operand.

Modulus-equals (%=)
Performs the modulus operation on the value of the lefthand operand and the righthand operand, then assigns the result to the lefthand operand.

Bitwise-XOR-equals (^=)
Performs a bitwise XOR on the lefthand and righthand operands, then assigns the result to the lefthand operand.

Bitwise-AND-equals (&=)
Performs a bitwise AND on the value of the lefthand operand and the righthand operand, then assigns the result to the lefthand operand.

Bitwise-OR-equals (|=)
Performs a bitwise OR on the value of the lefthand operand and the righthand operand, then assigns the result to the lefthand operand.

Concatenate-equals (.=)
Concatenates the righthand operand to the value of the lefthand operand, then assigns the result to the lefthand operand.

Miscellaneous Operators
The remaining PHP operators are for error suppression, executing an external command, and selecting values:

Error suppression (@)
Some operators or functions can generate error messages. The error suppression operator, discussed in full in Chapter 13, is used to prevent these messages from being created.

Execution (`...`)
The backtick operator executes the string contained between the backticks as a shell command and returns the output. For example:

$listing = `ls -ls /tmp`;
echo $listing;
Conditional (?:)
The conditional operator is, depending on the code you look at, either the most overused or most underused operator. It is the only ternary (three-operand) operator and is therefore sometimes just called the ternary operator.

The conditional operator evaluates the expression before the ?. If the expression is true, the operator returns the value of the expression between the ? and :; otherwise, the operator returns the value of the expression after the :. For instance:

">
If text for the link $url is present in the variable $linktext, it is used as the text for the link; otherwise, the URL itself is displayed.

more >>>>>>> Expressions and Operators

Data Types

Data Types

PHP provides eight types of values, or data types. Four are scalar (single-value) types: integers, floating-point numbers, strings, and booleans. Two are compound (collection) types: arrays and objects. The remaining two are special types: resource and NULL. Numbers, booleans, resources, and NULL are discussed in full here, while strings, arrays, and objects are big enough topics that they get their own chapters (Chapter 4, Chapter 5, and Chapter 6).

Integers
Integers are whole numbers, like 1, 12, and 256. The range of acceptable values varies according to the details of your platform but typically extends from -2,147,483,648 to +2,147,483,647. Specifically, the range is equivalent to the range of the long data type of your C compiler. Unfortunately, the C standard doesn't specify what range that long type should have, so on some systems you might see a different integer range.

Integer literals can be written in decimal, octal, or hexadecimal. Decimal values are represented by a sequence of digits, without leading zeros. The sequence may begin with a plus (+) or minus (-) sign. If there is no sign, positive is assumed. Examples of decimal integers include the following:

1998
-641
+33
Octal numbers consist of a leading 0 and a sequence of digits from 0 to 7. Like decimal numbers, octal numbers can be prefixed with a plus or minus. Here are some example octal values and their equivalent decimal values:

0755 // decimal 493
+010 // decimal 8
Hexadecimal values begin with 0x, followed by a sequence of digits (0-9) or letters (A-F). The letters can be upper- or lowercase but are usually written in capitals. Like decimal and octal values, you can include a sign in hexadecimal numbers:

0xFF // decimal 255
0x10 // decimal 16
-0xDAD1 // decimal -56017
If you try to store a too-large integer in a variable, it will automatically be turned into a floating-point number.

Use the is_int( ) function (or its is_integer( ) alias) to test whether a value is an integer:

if (is_int($x)) {
// $x is an integer
}
Floating-Point Numbers
Floating-point numbers (often referred to as real numbers) represent numeric values with decimal digits. Like integers, their limits depend on your machine's details. PHP floating-point numbers are equivalent to the range of the double data type of your C compiler. Usually, this allows numbers between 1.7E-308 and 1.7E+308 with 15 digits of accuracy. If you need more accuracy or a wider range of integer values, you can use the BC or GMP extensions. See Appendix B for an overview of the BC and GMP extensions.

PHP recognizes floating-point numbers written in two different formats. There's the one we all use every day:

3.14
0.017
-7.1
but PHP also recognizes numbers in scientific notation:

0.314E1 // 0.314*101, or 3.14
17.0E-3 // 17.0*10-3, or 0.017
Floating-point values are only approximate representations of numbers. For example, on many systems 3.5 is actually represented as 3.4999999999. This means you must take care to avoid writing code that assumes floating-point numbers are represented completely accurately, such as directly comparing two floating-point values using ==. The normal approach is to compare to several decimal places:

if (int($a * 1000) == int($b * 1000)) {
// numbers equal to three decimal places
Use the is_float( ) function (or its is_real( ) alias) to test whether a value is a floating point number:

if (is_float($x)) {
// $x is a floating-point number
}
Strings
Because strings are so common in web applications, PHP includes core-level support for creating and manipulating strings. A string is a sequence of characters of arbitrary length. String literals are delimited by either single or double quotes:

'big dog'
"fat hog"
Variables are expanded within double quotes, while within single quotes they are not:

$name = "Guido";
echo "Hi, $name\n";
echo 'Hi, $name';
Hi, Guido
Hi, $name
Double quotes also support a variety of string escapes, as listed in Table 2-2.

Table 2-2. Escape sequences in double-quoted strings

Escape sequence

Character represented

\"

Double quotes

\n

Newline

\r

Carriage return

\t

Tab

\\

Backslash

\$

Dollar sign

\{

Left brace

\}

Right brace

\[

Left bracket

\]

Right bracket

\0 through \777

ASCII character represented by octal value

\x0 through \xFF

ASCII character represented by hex value

A single-quoted string only recognizes \\ to get a literal backslash and \' to get a literal single quote:

$dos_path = 'C:\\WINDOWS\\SYSTEM';
$publisher = 'Tim O\'Reilly';
echo "$dos_path $publisher\n";
C:\WINDOWS\SYSTEM Tim O'Reilly
To test whether two strings are equal, use the == comparison operator:

if ($a == $b) { echo "a and b are equal" }
Use the is_string( ) function to test whether a value is a string:

if (is_string($x)) {
// $x is a string
}
PHP provides operators and functions to compare, disassemble, assemble, search, replace, and trim strings, as well as a host of specialized string functions for working with HTTP, HTML, and SQL encodings. Because there are so many string-manipulation functions, we've devoted a whole chapter (Chapter 4) to covering all the details.

2.2.4 Booleans
A boolean value represents a "truth value"—it says whether something is true or not. Like most programming languages, PHP defines some values as true and others as false. Truth and falseness determine the outcome of conditional code such as:

if ($alive) { ... }
In PHP, the following values are false:

The keyword false

The integer 0

The floating-point value 0.0

The empty string ("") and the string "0"

An array with zero elements

An object with no values or functions

The NULL value

Any value that is not false is true, including all resource values (which are described later, in Section 2.2.7).

PHP provides true and false keywords for clarity:

$x = 5; // $x has a true value
$x = true; // clearer way to write it
$y = ""; // $y has a false value
$y = false; // clearer way to write it
Use the is_bool( ) function to test whether a value is a boolean:

if (is_bool($x)) {
// $x is a boolean
}
2.2.5 Arrays
An array holds a group of values, which you can identify by position (a number, with zero being the first position) or some identifying name (a string):

$person[0] = "Edison";
$person[1] = "Wankel";
$person[2] = "Crapper";

$creator['Light bulb'] = "Edison";
$creator['Rotary Engine'] = "Wankel";
$creator['Toilet'] = "Crapper";
The array( ) construct creates an array:

$person = array('Edison', 'Wankel', 'Crapper');
$creator = array('Light bulb' => 'Edison',
'Rotary Engine' => 'Wankel',
'Toilet' => 'Crapper');
There are several ways to loop across arrays, but the most common is a foreach loop:

foreach ($person as $name) {
echo "Hello, $name\n";
}
foreach ($creator as $invention => $inventor) {
echo "$inventor created the $invention\n";
}
Hello, Edison
Hello, Wankel
Hello, Crapper
Edison created the Light bulb
Wankel created the Rotary Engine
Crapper created the Toilet
You can sort the elements of an array with the various sort functions:

sort($person);
// $person is now array('Crapper', 'Edison', 'Wankel')

asort($creator);
// $creator is now array('Toilet' => 'Crapper',
// 'Light bulb' => 'Edison',
// 'Rotary Engine' => 'Wankel');
Use the is_array( ) function to test whether a value is an array:

if (is_array($x)) {
// $x is an array
}
There are functions for returning the number of items in the array, fetching every value in the array, and much more. Arrays are described in Chapter 5.

2.2.6 Objects
PHP supports object-oriented programming (OOP). OOP promotes clean modular design, simplifies debugging and maintenance, and assists with code reuse.

Classes are the unit of object-oriented design. A class is a definition of a structure that contains properties (variables) and methods (functions). Classes are defined with the class keyword:

class Person {
var $name = '';

function name ($newname = NULL) {
if (! is_null($newname)) {
$this->name = $newname;
}
return $this->name;
}
}
Once a class is defined, any number of objects can be made from it with the new keyword, and the properties and methods can be accessed with the -> construct:

$ed = new Person;
$ed->name('Edison');
printf("Hello, %s\n", $ed->name);
$tc = new Person;
$tc->name('Crapper');
printf("Look out below %s\n", $tc->name);
Hello, Edison
Look out below Crapper
Use the is_object( ) function to test whether a value is an object:

if (is_object($x)) {
// $x is an object
}
Chapter 6 describes classes and objects in much more detail, including inheritance, encapsulation (or the lack thereof ), and introspection.

2.2.7 Resources
Many modules provide several functions for dealing with the outside world. For example, every database extension has at least a function to connect to the database, a function to send a query to the database, and a function to close the connection to the database. Because you can have multiple database connections open at once, the connect function gives you something by which to identify that connection when you call the query and close functions: a resource.

Resources are really integers under the surface. Their main benefit is that they're garbage collected when no longer in use. When the last reference to a resource value goes away, the extension that created the resource is called to free any memory, close any connection, etc. for that resource:

$res = database_connect( ); // fictitious function
database_query($res);
$res = "boo"; // database connection automatically closed
The benefit of this automatic cleanup is best seen within functions, when the resource is assigned to a local variable. When the function ends, the variable's value is reclaimed by PHP:

function search ( ) {
$res = database_connect( );
$database_query($res);
}
When there are no more references to the resource, it's automatically shut down.

That said, most extensions provide a specific shutdown or close function, and it's considered good style to call that function explicitly when needed rather than to rely on variable scoping to trigger resource cleanup.

Use the is_resource( ) function to test whether a value is a resource:

if (is_resource($x)) {
// $x is a resource
}
2.2.8 NULL
There's only one value of the NULL data type. That value is available through the case-insensitive keyword NULL. The NULL value represents a variable that has no value (similar to Perl's undef or Python's None):

$aleph = "beta";
$aleph = null; // variable's value is gone
$aleph = Null; // same
$aleph = NULL; // same
Use the is_null( ) function to test whether a value is NULL—for instance, to see whether a variable has a value:

if (is_null($x)) {
// $x is NULL
}

more>>>>>>>> Data types

Lexical Structure

Lexical Structure

The lexical structure of a programming language is the set of basic rules that governs how you write programs in that language. It is the lowest-level syntax of the language and specifies such things as what variable names look like, what characters are used for comments, and how program statements are separated from each other.

Case Sensitivity
The names of user-defined classes and functions, as well as built-in constructs and keywords such as echo, while, class, etc., are case-insensitive. Thus, these three lines are equivalent:

echo("hello, world");
ECHO("hello, world");
EcHo("hello, world");
Variables, on the other hand, are case-sensitive. That is, $name, $NAME, and $NaME are three different variables.

Statements and Semicolons
A statement is a collection of PHP code that does something. It can be as simple as a variable assignment or as complicated as a loop with multiple exit points. Here is a small sample of PHP statements, including function calls, assignment, and an if test:

echo "Hello, world";
myfunc(42, "O'Reilly");
$a = 1;
$name = "Elphaba";
$b = $a / 25.0;
if ($a == $b) { echo "Rhyme? And Reason?"; }
PHP uses semicolons to separate simple statements. A compound statement that uses curly braces to mark a block of code, such as a conditional test or loop, does not need a semicolon after a closing brace. Unlike in other languages, in PHP the semicolon before the closing brace is not optional:

if ($needed) {
echo "We must have it!"; // semicolon required here
} // no semicolon required here
The semicolon is optional before a closing PHP tag:

if ($a == $b) { echo "Rhyme? And Reason?"; }
echo "Hello, world" // no semicolon required before closing tag
?>
It's good programming practice to include optional semicolons, as they make it easier to add code later.

2.1.3 Whitespace and Line Breaks
In general, whitespace doesn't matter in a PHP program. You can spread a statement across any number of lines, or lump a bunch of statements together on a single line. For example, this statement:

raise_prices($inventory, $inflation, $cost_of_living, $greed);
could just as well be written with more whitespace:

raise_prices (
$inventory ,
$inflation ,
$cost_of_living ,
$greed
) ;
or with less whitespace:

raise_prices($inventory,$inflation,$cost_of_living,$greed);
You can take advantage of this flexible formatting to make your code more readable (by lining up assignments, indenting, etc.). Some lazy programmers take advantage of this free-form formatting and create completely unreadable code—this isn't recommended.

Comments
Comments give information to people who read your code, but they are ignored by PHP. Even if you think you're the only person who will ever read your code, it's a good idea to include comments in your code—in retrospect, code you wrote months ago can easily look as though a stranger wrote it.

Good practice is to make your comments sparse enough not to get in the way of the code itself and plentiful enough that you can use the comments to tell what's happening. Don't comment obvious things, lest you bury the comments that describe tricky things. For example, this is worthless:

$x = 17; // store 17 into the variable $x
whereas this may well help whoever will maintain your code:

// convert &#nnn; entities into characters
$text = preg_replace('/&#([0-9])+);/e', "chr('\\1')", $text);
PHP provides several ways to include comments within your code, all of which are borrowed from existing languages such as C, C++, and the Unix shell. In general, use C-style comments to comment out code, and C++-style comments to comment on code.

Shell-style comments
When PHP encounters a hash mark (#) within the code, everything from the hash mark to the end of the line or the end of the section of PHP code (whichever comes first) is considered a comment. This method of commenting is found in Unix shell scripting languages and is useful for annotating single lines of code or making short notes.

Because the hash mark is visible on the page, shell-style comments are sometimes used to mark off blocks of code:

#######################
## Cookie functions
#######################
Sometimes they're used before a line of code to identify what that code does, in which case they're usually indented to the same level as the code:

if ($double_check) {
# create an HTML form requesting that the user confirm the action
echo confirmation_form( );
}
Short comments on a single line of code are often put on the same line as the code:

$value = $p * exp($r * $t); # calculate compounded interest
When you're tightly mixing HTML and PHP code, it can be useful to have the closing PHP tag terminate the comment:

Then another
Then another 4
2.1.4.2 C++ comments
When PHP encounters two slash characters (//) within the code, everything from the slashes to the end of the line or the end of the section of code, whichever comes first, is considered a comment. This method of commenting is derived from C++. The result is the same as the shell comment style.

Here are the shell-style comment examples, rewritten to use C++ comments:

////////////////////////
// Cookie functions
////////////////////////

if ($double_check) {
// create an HTML form requesting that the user confirm the action
echo confirmation_form( );
}

$value = $p * exp($r * $t); // calculate compounded interest

Then another
Then another 4
2.1.4.3 C comments
While shell- and C++-style comments are useful for annotating code or making short notes, longer comments require a different style. As such, PHP supports block comments, whose syntax comes from the C programming language. When PHP encounters a slash followed by an asterisk (/*), everything after that until it encounters an asterisk followed by a slash (*/) is considered a comment. This kind of comment, unlike those shown earlier, can span multiple lines.

Here's an example of a C-style multiline comment:

/* In this section, we take a bunch of variables and
assign numbers to them. There is no real reason to
do this, we're just having fun.
*/
$a = 1; $b = 2; $c = 3; $d = 4;
Because C-style comments have specific start and end markers, you can tightly integrate them with code. This tends to make your code harder to read, though, so it is frowned upon:

/* These comments can be mixed with code too,
see? */ $e = 5; /* This works just fine. */
C-style comments, unlike the other types, continue past end markers. For example:

$l = 12;
$m = 13;
/* A comment begins here
?>

Some stuff you want to be HTML.



*/
echo("l=$l m=$m n=$n\n");
?>

Now this is regular HTML...


l=12 m=13 n=

Now this is regular HTML...


You can indent, or not indent, comments as you like:

/* There are no
special indenting or spacing
rules that have to be followed, either.


*/
C-style comments can be useful for disabling sections of code. In the following example, we've disabled the second and third statements by including them in a block comment. To enable the code, all we have to do is remove the comment markers:

$f = 6;
/* $g = 7; # This is a different style of comment
$h = 8;
*/
However, you have to be careful not to attempt to nest block comments:

$i = 9;
/* $j = 10; /* This is a comment */
$k = 11;
Here is some comment text.
*/
In this case, PHP tries (and fails) to execute the (non-)statement Here is some comment text and returns an error.

Literals
A literal is a data value that appears directly in a program. The following are all literals in PHP:

2001
0xFE
1.4142
"Hello World"
'Hi'
true
null
Identifiers
An identifier is simply a name. In PHP, identifiers are used to name variables, functions, constants, and classes. The first character of an identifier must be either an ASCII letter (uppercase or lowercase), the underscore character (_), or any of the characters between ASCII 0x7F and ASCII 0xFF. After the initial character, these characters and the digits 0-9 are valid.

Variable names
Variable names always begin with a dollar sign ($) and are case-sensitive. Here are some valid variable names:

$bill
$head_count
$MaximumForce
$I_HEART_PHP
$_underscore
$_int
Here are some illegal variable names:

$not valid
$|
$3wa
These variables are all different:

$hot_stuff $Hot_stuff $hot_Stuff $HOT_STUFF
2.1.6.2 Function names
Function names are not case-sensitive (functions are discussed in more detail in Chapter 3). Here are some valid function names:

tally
list_all_users
deleteTclFiles
LOWERCASE_IS_FOR_WIMPS
_hide
These function names refer to the same function:

howdy HoWdY HOWDY HOWdy howdy
Class names
Class names follow the standard rules for PHP identifiers and are not case-sensitive. Here are some valid class names:

Person
account
The class name stdClass is reserved.

Constants
A constant is an identifier for a simple value; only scalar values—boolean, integer, double, and string—can be constants. Once set, the value of a constant cannot change. Constants are referred to by their identifiers and are set using the define( ) function:

define('PUBLISHER', "O'Reilly & Associates");
echo PUBLISHER;
2.1.7 Keywords
A keyword is a word reserved by the language for its core functionality—you cannot give a variable, function, class, or constant the same name as a keyword. Table 2-1 lists the keywords in PHP, which are case-insensitive.

Table 2-1. PHP core language keywords
and
$argc
$argv
as
break
case
cfunction
class
continue
declare
default
die
do
E_ALL
echo
E_ERROR
else
elseif
empty
enddeclare
endfor
endforeach
endif
endswitch
E_PARSE
eval
E_WARNING
exit
extends
FALSE
for
foreach
function
$HTTP_COOKIE_VARS
$HTTP_ENV_VARS
$HTTP_GET_VARS
$HTTP_POST_FILES
$HTTP_POST_VARS
$HTTP_SERVER_VARS
if
include
include_once
global
list
new
not
NULL
old_function
or
parent
PHP_OS
$PHP_SELF
PHP_VERSION
print
require
require_once
return
static
stdClass
switch
$this
TRUE
var
virtual
while
xor
_  _FILE_  _
_  _LINE_  _
_  _sleep
_  _wakeup
$_COOKIE
$_ENV
$_FILES
$_GET
$_POST
$_SERVER

In addition, you cannot use an identifier that is the same as a built-in PHP function.

For a complete list of these, see Appendix A.

Language Basics

Language Basics

This chapter provides a whirlwind tour of the core PHP language, covering such basic topics as data types, variables, operators, and flow control statements. PHP is strongly influenced by other programming languages, such as Perl and C, so if you've had experience with those languages, PHP should be easy to pick up. If PHP is one of your first programming languages, don't panic. We start with the basic units of a PHP program and build up your knowledge from there.

more>>>>> hi

Walk Through PHP

Walk Through PHP

PHP pages are HTML pages with PHP commands embedded in them. This is in contrast to many other dynamic web-page solutions, which are scripts that generate HTML. The web server processes the PHP commands and sends their output (and any HTML from the file) to the browser. Example 1-1 shows a complete PHP page.

Example 1-1. hello.php





Save the contents of Example 1-1 to a file, hello.php, and point your browser to it. The results appear in Figure 1-3.

Figure 1-3. Output of hello.php

The PHP echo command produces output (the string "Hello, world!"), which is inserted into 
the HTML file. In this example, the PHP code is placed between  tags. There are other 
ways to tag your PHP code—see Chapter 2 for a full description. 
Configuration Page
The PHP function phpinfo( ) creates an HTML page full of information on how PHP was installed.
You can use it to see whether you have particular extensions installed, or whether the php.ini file 
has been customized. Example 1-2 is a complete page that displays the phpinfo( ) page. 
Using phpinfo( )

Figure 1-4 shows the first part of the output of Example 1-2.
Figure 1-4. Partial output of phpinfo( )

Forms
Example 1-3 creates and processes a form. When the user submits the form, the information typed into the name field is sent back to this page. The PHP code tests for a name field and displays a greeting if it finds one.

Processing a form




The form and the message are shown in Figure 1-5.

Figure 1-5. Form and greeting

PHP programs access form values through the $_POST and $_GET array variables. Chapter 7 discusses forms and form processing in more detail.

Databases
PHP supports all the popular database systems, including MySQL, PostgreSQL, Oracle, Sybase,

and ODBC-compliant databases. Figure 1-6 shows part of a MySQL database with two tables: actors, which assigns a unique identifier to each actor who played James Bond; and movies, which records each movie's name, release date, and the identifier of the Bond actor.

Figure 1-6. Contents of the Bond tables

The code in Example 1-4 connects to the database, issues a query to match up movies with the actor's name, and produces a table as output. It uses the DB library to access a MySQL database, issue a query, and display the results. The bracketing construct runs PHP code and prints the result.

Querying the Bond database
Bond Movies



getMessage( ));
}

// issue the query
$sql = "SELECT movies.title,movies.year,actors.name
FROM movies,actors
WHERE movies.actor=actors.id
ORDER BY movies.year ASC";

$q = $db->query($sql);
if (DB::iserror($q)) {
die($q->getMessage( ));
}

// generate table
while ($q->fetchInto($row)) {
?>






MovieYearActor





The output of Example 1-4 is shown in Figure 1-7.

Figure 1-7. Output of the database query

Database-provided dynamic content drives the news and e-commerce sites at the heart of the Web. More details on accessing databases from PHP are given in Chapter 8.

1.4.4 Graphics
With PHP, you can easily create and manipulate images using the GD extension. Example 1-5 provides a text-entry field that lets the user specify the text for a button. It takes an empty button image file, and on it centers the text passed as the GET parameter "message". The result is then sent back to the browser as a PNG image.

Example 1-5. Dynamic buttons

// center
$dx = abs($tsize[2]-$tsize[0]);
$dy = abs($tsize[5]-$tsize[3]);
$x = ( imagesx($im) - $dx ) / 2;
$y = ( imagesy($im) - $dy ) / 2 + $dy;

// draw text
$black = ImageColorAllocate($im,0,0,0);
ImageTTFText($im, $size, 0, $x, $y, $black, $font, $_GET['message']);

// return image
header('Content-type: image/png');
ImagePNG($im);
exit;
}
?>

Button Form




The form generated by Example 1-5 is shown in Figure 1-8. The button created is shown in Figure 1-9.

Figure 1-8. Button-creation form

Figure 1-9. Button created

You can use GD to dynamically resize images, produce graphs, and much more. PHP also has several extensions to generate documents in Adobe's popular PDF format. Chapter 9 covers dynamic image generation in depth, and Chapter 10 shows how to create Adobe PDF files.

1.4.5 From the Shell
If you compile PHP without specifying a specific web server type, you get a PHP interpreter as a program instead of a web server module. This lets you write PHP scripts that use PHP functionality such as databases and graphics and yet are callable from the command line.

For example, Example 1-6 also creates buttons. However, it is run from the command line, not from a web server. The -q option to the php executable inhibits the generation of HTTP headers.

Example 1-6. Shell-based PHP program to create a button
#!/usr/local/bin/php -q

list(, $filename, $message) = $argv;

// load font and image, calculate width of text
$font = 'Arial.ttf';
$size = 12;
$im = ImageCreateFromPNG('button.png');
$tsize = imagettfbbox($size,0,$font,$message);

// center
$dx = abs($tsize[2]-$tsize[0]);
$dy = abs($tsize[5]-$tsize[3]);
$x = ( imagesx($im) - $dx ) / 2;
$y = ( imagesy($im) - $dy ) / 2 + $dy;

// draw text
$black = ImageColorAllocate($im,0,0,0);
ImageTTFText($im, $size, 0, $x, $y, $black, $font, $message);

// return image
ImagePNG($im, $filename);
?>
Save Example 1-6 to button-cli and run it:

# ./button-cli
usage: button-cli filename message
# ./button-cli php-button.png "PHP Button"
# ls -l php-button.png
-rwxr-xr-x 1 gnat gnat 1837 Jan 21 22:17 php-button.png
Now that you've had a taste of what is possible with PHP, you are ready to learn how to program in PHP. We start with the basic structure of the language, with special focus given to user-defined functions, string manipulation, and object-oriented programming. Then we move to specific application areas such as the Web, databases, graphics, XML, and security. We finish with quick references to the built-in functions and extensions. Master these chapters, and you've mastered PHP!

more >>>>>>> PhP

Installing PHP

Installing PHP

PHP is available for many operating systems and platforms. The most common setup, however, is to use PHP as a module for the Apache web server on a Unix machine. This section briefly describes how to install Apache with PHP. If you're interested in running PHP on Windows, see Chapter 15, which explains your many options.

To install Apache with PHP, you'll need a Unix machine with an ANSI-compliant C compiler, and around 5 MB of available disk space for source and object files. You'll also need Internet access to fetch the source code for PHP and Apache.

Start by downloading the source distributions of PHP and Apache. The latest files are always available respectively. Store the files in the same directory, so that you have:

-rw-r--r-- 1 gnat wheel 2177983 Oct 9 09:34 apache_1.3.22.tar.gz
-rw-r--r-- 1 gnat wheel 3371385 Dec 10 14:29 php-4.1.1.tar.gz
Now uncompress and extract the distributions:

# gunzip -c apache_1.3.22.tar.gz | tar xf -
# gunzip -c php-4.1.1.tar.gz | tar xf -
Each distribution unpacks into its own subdirectory, as follows:

drwxr-xr-x 8 gnat wheel 512 Dec 16 11:26 apache_1.3.22
drwxr-xr-x 16 gnat wheel 2048 Dec 21 23:48 php-4.1.1
The next step is to configure Apache, then configure PHP, telling it where the Apache source is and specifying the various other features that you want built into PHP. You'll probably want to customize the configurations of Apache and PHP. For instance, provide the --prefix=/some/path option to Apache's configure to change where Apache expects its configuration files and utilities. Similarly, typical options for PHP include --with-apache to identify the location of the Apache source tree, --enable-inline-optimizations to enable compilation options that give a faster PHP interpreter, and --with-mysql to identify where MySQL was installed. Each configuration creates detailed output as it goes:

# cd apache_1.3.22
# ./configure --prefix=/usr/local/apache
Configuring for Apache, Version 1.3.22
+ using installation path layout: Apache (config.layout)
Creating Makefile
Creating Configuration.apaci in src
Creating Makefile in src
+ configured for FreeBSD 4.2 platform
+ setting C compiler to gcc
...
# cd ../php-4.1.1
# ./configure --with-apache=../apache_1.3.22 --enable-inline-optimization \
--with-mysql=/usr
creating cache ./config.cache
checking for a BSD compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking whether make sets ${MAKE}... yes
checking for working aclocal... missing
checking for working autoconf... found
checking for working automake... missing
checking for working autoheader... found
checking for working makeinfo... found
Updated php_version.h
...
For a full list of available configure options for each package, see the output of:

./configure --help
Now you can build and install PHP:

# make
# make install
These commands also install the PEAR libraries and copy the compiled Apache module to the Apache source tree.

Finally, change directory back to the Apache directory. Reconfigure Apache, telling it about the newly built PHP module, and compile and install it:

# cd ../apache_1.3.22
# ./configure --prefix=/usr/local/apache --activate-module=src/modules/php4/libphp4.a
# make
# make install
You now have Apache installed in /usr/local/apache, with PHP enabled. You also have PHP's extensions installed (probably in /usr/local/lib/php). You still need to configure the web server to process .php pages with the PHP interpreter, and start the web server. You may also want to change the PHP configuration.

Note that if you already have Apache installed and running on your server, it is possible to add PHP to the existing Apache instance without recompiling it. These days, this is actually the most common way to build PHP. Instead of using --with-apache on your configure line, use --with-apxs. You don't need the Apache source code in this case; only the apxs script needs to be available on your server. Most Linux distributions include this script and the corresponding files in their apache-devel packages.

PHP's configuration goes in a file called php.ini. The settings in this file control the behavior of PHP features, such as session handling and form processing. Later chapters will refer to php.ini options, but in general the code in this book does not require a customized configuration. See for more information on php.ini configuration.

Once you have a web server, you'll need to tell it that .php files are to be handled by the PHP module. Put this in Apache's httpd.conf file, and restart the web server:

AddType application/x-httpd-php .php
The PHP and Apache source directories both include files called INSTALL that contain detailed instructions on troubleshooting and building those programs. If you want a nonstandard installation, or if you encounter problems with the instructions presented here, be sure to read the INSTALL files.



and more >>>>>>> php

Brief History of PHP

Brief History of PHP

Rasmus Lerdorf first conceived of PHP in 1994, but the PHP that people use today is quite different from the initial version. To understand how PHP got where it is today, it is useful to know the historical evolution of the language. Here's that story, as told by Rasmus.

1.2.1 The Evolution of PHP
Here is the PHP 1.0 announcement that I posted to the Usenet newsgroup comp.infosystems.www.authoring.cgi in June 1995:

From: This e-mail address is being protected from spambots. You need JavaScript enabled to view it (Rasmus Lerdorf)
Subject: Announce: Personal Home Page Tools (PHP Tools)
Date: 1995/06/08
Message-ID: <>#1/1
organization: none
newsgroups: comp.infosystems.

Announcing the Personal Home Page Tools (PHP Tools) version 1.0.

These tools are a set of small tight cgi binaries written in C.
They perform a number of functions including:

. Logging accesses to your pages in your own private log files
. Real-time viewing of log information
. Providing a nice interface to this log information
. Displaying last access information right on your pages
. Full daily and total access counters
. Banning access to users based on their domain
. Password protecting pages based on users' domains
. Tracking accesses ** based on users' e-mail addresses **
. Tracking referring URL's - HTTP_REFERER support
. Performing server-side includes without needing server support for it
. Ability to not log accesses from certain domains (ie. your own)
. Easily create and display forms
. Ability to use form information in following documents

Here is what you don't need to use these tools:

. You do not need root access - install in your ~/public_html dir
. You do not need server-side includes enabled in your server
. You do not need access to Perl or Tcl or any other script interpreter
. You do not need access to the httpd log files

The only requirement for these tools to work is that you have
the ability to execute your own cgi programs. Ask your system
administrator if you are not sure what this means.

The tools also allow you to implement a guestbook or any other
form that needs to write information and display it to users
later in about 2 minutes.

The tools are in the public domain distributed under the GNU
Public License. Yes, that means they are free!

For a complete demonstration of these tools, point your browser
at: more

--
Rasmus Lerdorf
This e-mail address is being protected from spambots. You need JavaScript enabled to view it

Note that the URL and email address shown in this message are long gone. The language of this announcement reflects the concerns that people had at the time, such as password-protecting pages, easily creating forms, and accessing form data on subsequent pages. The announcement also illustrates PHP's initial positioning as a framework for a number of useful tools.

The announcement talks only about the tools that came with PHP, but behind the scenes the goal was to create a framework to make it easy to extend PHP and add more tools. The business logic for these add-ons was written in C—a simple parser picked tags out of the HTML and called the various C functions. It was never my plan to create a scripting language.

So, what happened?

I started working on a rather large project for the University of Toronto that needed a tool to pull together data from various places and present a nice web-based administration interface. Of course, I decided that PHP would be ideal for the task, but for performance reasons, the various small tools of PHP 1 had to be brought together better and integrated into the web server.

Initially, I made some hacks to the NCSA web server, to patch it to support the core PHP functionality. The problem with this approach was that as a user, you had to replace your web-server software with this special, hacked-up version. Fortunately, Apache was starting to gain momentum around this time, and the Apache API made it easier to add functionality like PHP to the server.

Over the next year or so, a lot was done and the focus changed quite a bit. Here's the PHP Version 2 (PHP/FI) announcement I sent in April 1996:

From: This e-mail address is being protected from spambots. You need JavaScript enabled to view it (Rasmus Lerdorf)
Subject: ANNOUNCE: PHP/FI Server-side HTML-Embedded Scripting Language
Date: 1996/04/16
Newsgroups: comp.infosystems.www.authoring.cgi

PHP/FI is a server-side HTML embedded scripting language. It has built-in
access logging and access restriction features and also support for
embedded SQL queries to mSQL and/or Postgres95 backend databases.

It is most likely the fastest and simplest tool available for creating
database-enabled web sites.

It will work with any UNIX-based web server on every UNIX flavour out
there. The package is completely free of charge for all uses including
commercial.

Feature List:

. Access Logging
Log every hit to your pages in either a dbm or an mSQL database.
Having hit information in a database format makes later analysis easier.
. Access Restriction
Password protect your pages, or restrict access based on the refering URL
plus many other options.
. mSQL Support
Embed mSQL queries right in your HTML source files
. Postgres95 Support
Embed Postgres95 queries right in your HTML source files
. DBM Support
DB,DBM,NDBM and GDBM are all supported
. RFC-1867 File Upload Support
Create file upload forms
. Variables, Arrays, Associative Arrays
. User-Defined Functions with static variables + recursion
. Conditionals and While loops
Writing conditional dynamic web pages could not be easier than with
the PHP/FI conditionals and looping support
. Extended Regular Expressions
Powerful string manipulation support through full regexp support
. Raw HTTP Header Control
Lets you send customized HTTP headers to the browser for advanced
Features such as cookies.
. Dynamic GIF Image Creation
Thomas Boutell's GD library is supported through an easy-to-use set of
tags.

It can be downloaded from the File Archive at:

--
Rasmus Lerdorf
This e-mail address is being protected from spambots. You need JavaScript enabled to view it
This was the first time the term "scripting language" was used. PHP 1's simplistic tag-replacement code was replaced with a parser that could handle a more sophisticated embedded tag language. By today's standards, the tag language wasn't particularly sophisticated, but compared to PHP 1 it certainly was.

The main reason for this change was that few people who used PHP 1 were actually interested in using the C-based framework for creating add-ons. Most users were much more interested in being able to embed logic directly in their web pages for creating conditional HTML, custom tags, and other such features. PHP 1 users were constantly requesting the ability to add the hit-tracking footer or send different HTML blocks conditionally. This led to the creation of an if tag. Once you have if, you need else as well. And from there, it's a slippery slope to the point where, whether you want to or not, you end up writing an entire scripting language.

By mid-1997, PHP Version 2 had grown quite a bit and had attracted a lot of users, but there were still some stability problems with the underlying parsing engine. The project was also still mostly a one-man effort, with a few contributions here and there. At this point, Zeev Suraski and Andi Gutmans in Tel Aviv volunteered to rewrite the underlying parsing engine, and we agreed to make their rewrite the base for PHP Version 3. Other people also volunteered to work on other parts of PHP, and the project changed from a one-person effort with a few contributors to a true open source project with many developers around the world.

Here is the PHP 3.0 announcement from June 1998:

June 6, 1998 -- The PHP Development Team announced the release of PHP 3.0,
the latest release of the server-side scripting solution already in use on
over 70,000 World Wide Web sites.

This all-new version of the popular scripting language includes support
for all major operating systems (Windows 95/NT, most versions of Unix,
and Macintosh) and web servers (including Apache, Netscape servers,
WebSite Pro, and Microsoft Internet Information Server).

PHP 3.0 also supports a wide range of databases, including Oracle, Sybase, Solid,
MySQ, mSQL, and PostgreSQL, as well as ODBC data sources.

New features include persistent database connections, support for the
SNMP and IMAP protocols, and a revamped C API for extending the language
with new features.

"PHP is a very programmer-friendly scripting language suitable for
people with little or no programming experience as well as the
seasoned web developer who needs to get things done quickly. The
best thing about PHP is that you get results quickly," said
Rasmus Lerdorf, one of the developers of the language.

"Version 3 provides a much more powerful, reliable and efficient
implementation of the language, while maintaining the ease of use and
rapid development that were the key to PHP's success in the past",
added Andi Gutmans, one of the implementors of the new language core.

"At Circle Net we have found PHP to be the most robust platform for
rapid web-based application development available today," said Troy
Cobb, Chief Technology Officer at Circle Net, Inc. "Our use of PHP
has cut our development time in half, and more than doubled our client
satisfaction. PHP has enabled us to provide database-driven dynamic
solutions which perform at phenomenal speeds."

PHP 3.0 is available for free download in source form and binaries for
several platforms at

The PHP Development Team is an international group of programmers who
lead the open development of PHP and related projects.

For more information, the PHP Development Team can be contacted at

After the release of PHP 3, usage really started to take off. Version 4 was prompted by a number of developers who were interested in making some fundamental changes to the architecture of PHP. These changes included abstracting the layer between the language and the web server, adding a thread-safety mechanism, and adding a more advanced, two-stage parse/execute tag-parsing system. This new parser, primarily written by Zeev and Andi, was named the Zend engine. After a lot of work by a lot of developers, PHP 4.0 was released on May 22, 2000.

Since that release, there have been a few minor releases of PHP 4, with the latest version as of this writing being 4.1.1. As this book goes to press, there is talk of PHP Version 5, which is likely to improve the internals of PHP's object system.

1.2.2 The Growth of PHP
Figures 1-1 and 1-2 show the growth of PHP as measured by the usage numbers collected by Netcraft since early 1998. Figure 1-1 shows the total number of unique IP addresses that report they are using Apache with the PHP module enabled. In November 2001, this number went beyond the one-million mark. The slight dip at the end of 2001 reflects the demise of a number of dot-coms that disappeared from the Web. The overall number of servers that Netcraft found also went down for the first time during this period.

Figure 1-1. The growth of PHP IP addresses

Figure 1-2 shows the number of actual domains that report they are using the PHP module. In November 2001, when Netcraft found 36,458,394 different domains, 7,095,691 ( just under 20%) of them were found to have PHP enabled. The domain figures represent the number of web sites using PHP, whereas IP addresses represent the number of physical servers running PHP.

Figure 1-2. The growth of PHP domains