PHP (PHP Hypertext Preprocessor) is a web scripting language. It was specifically designed to solve “the web problem.” PHP is easy to learn because it builds on the bits and pieces that most people already know. The pieces that you don’t know are filled in by excellent online documentation and many high-quality books. This simple approach to solving the web problem has caught on with an amazing number of people.
This pocket reference further simplifies things by focusing on the absolute essentials. It provides an overview of the main concepts needed for most web applications, followed by quick reference material for most of the main PHP functions.
آموزش برنامه نویسی PHP بصورت اختصاصی در mortezasaheb.ir
با خرید بسته آموزشی طراحی سایت اختصاصی mortezasaheb.ir برنامه نویس وب خواهید شد و میتوانید انواع سایتهای شخصی ، تجاری ، شرکتی ، فروشگاهی را طراحی کنید.
1.2 Installation and Configuration
PHP works with many different web servers in many different ways, but by far the most popular way to run PHP is as an Apache module with Apache 1.3.x. Full installation instructions for all the different ways to install PHP can be found in the PHP documentation. Here, I cover the Apache module installation.
If you are compiling from the PHP source tarball, follow the instructions in the INSTALL file found inside the PHP distribution file. A tarball is a compressed tar file. tar stands for tape archive, but these days it has little to do with tapes. It is simply a way to lump multiple files and directories into a single file for distribution. Normally tarballs have the .tar.gz extension to indicate a tar file compressed with gzip. To untar a tarball, use:
tar zxvf foo.tar.gz
On Windows, many utilities (including WinZip) understand tarballs.
If you are installing from a precompiled binary package such as an rpm file, most of the work should be done for you. But doublecheck that the Apache configuration described below is correct.
When you are using PHP as an Apache module, PHP processing is triggered by a special MIME type. This is defined in the Apache configuration file with a line similar to:
AddType application/x-httpd-php .php
This line tells Apache to treat all files that end with the .php extension as PHP files, which means that any file with that extension is parsed for PHP tags. The actual extension is completely arbitrary and you are free to change it to whatever you wish to use.
If you are running PHP as a dynamic shared object (DSO) module, you also need this line in your Apache configuration file:
LoadModule php4_module modules/libphp4.so
Note that in many default httpd.conf files you will find AddModule lines. These really aren’t necessary. They are only needed if you have a ClearModuleList directive somewhere in your httpd.conf file. I would suggest simply deleting the ClearModuleList directive and deleting all your AddModule lines. The idea behind ClearModuleList/AddModule is to make it possible to reorder already loaded modules in case module order is an issue. With most modules, the order that they are loaded — which governs the order they are called — is not important. And further, most binary distributions of Apache ship with most modules compiled as dynamically loadable modules, which means that if order is an issue for some reason, you can simply change the order of the LoadModule calls to fix it.
Don’t forget to restart your server after making changes to your httpd.conf file. Once the server is restarted, you can check to see if PHP is working by creating a file in your document root named info.php containing the single line:
<?php phpinfo( )?>
Load this up in your browser using http://your.domain.com/info.php. You should see all sorts of information about PHP. If you don’t see anything, try selecting “View Source” in your browser. If you see the phpinfo( ) line, you probably forgot (or mistyped) the AddType line in your httpd.conf file. If the browser tries to download the file instead, it means that the AddType is there, but the PHP module is not being triggered — perhaps because you forgot the LoadModule line.
Once you have verified that PHP is working, have a look at the PHP initialization file called php.ini. The phpinfo( ) page will tell you where PHP is expecting to find it. PHP functions fine without this file, but with all the default settings. If you want to change the defaults, or perhaps more importantly, you want to be immune from any changes to the defaults when you upgrade, you should create a php.ini file. The source distribution of PHP comes with a php.ini-dist file that you can rename and copy into the location specified in the phpinfo( ) output. The php.ini file itself is well-commented and self-explanatory for the most part.
You can also put configuration directives inside the Apache httpd.conf file, and, in certain cases, in individual .htaccess files. This is very useful for setting things per-directory or per-virtual host. If you have this line in the php.ini file:
include_path = ".:/usr/local/lib/php:.."
you can set this in your httpd.conf file with:
php_value include_path .:/usr/local/lib/php:..
There are four httpd.conf directives used for setting PHP directives:
php_value
For setting normal strings and values
php_flag
For setting boolean values
php_admin_value
For setting administrative values
php_admin_flag
For setting boolean administrative values
In addition, the normal values and booleans can be set in your .htaccess files, but only if the Apache AllowOverride setting (which sets what is allowed in a .htaccess file) includes "Options".
More information can be found at http://www.php.net/configuration.
1.3 Embedding PHP in HTML
You embed PHP code into a standard HTML page. For example, here’s how you can dynamically generate the title of an HTML document:
<html><head><title><?echo $title?></title>
</head>...
The <?echo $title?> portion of the document is replaced by the contents of the $title PHP variable. echo is a basic language statement that you can use to output data.
There are a few different ways to embed your PHP code. As you just saw, you can put PHP code between <? and ?> tags:
<? echo "Hello World"; ?>
This style is the most common way to embed PHP, but it is a problem if your PHP code needs to co-exist with XML, as XML may use that tagging style itself. If this is the case, turn off this style in the php.ini file with the short_open_tag directive. Another way to embed PHP code is within <?php and ?> tags:
<?php echo "Hello World"; ?>
This style is always available and is recommended when your PHP code needs to be portable to many different systems. Embedding PHP within <script> tags is another style that is always available:
<script language="php" > echo "Hello World";
</script>
One final style, in which the code is between <% and %> tags, is disabled by default:
<% echo "Hello World"; %>
You can turn on this style with the asp_tags directive in your php.ini file. The style is most useful when you are using Microsoft FrontPage or another HTML authoring tool that prefers that tag style for HTML-embedded scripts.
You can embed multiple statements by separating them with semicolons:
<?php
echo "Hello World";
echo "A second statement";
?>
It is legal to switch back and forth between HTML and PHP at any time. For example, if you want to output 100 <br /> tags for some reason, you can do it this way:
<?php for($i=0; $i<100; $i++) { ?>
<br />
<?php } ?>
Of course, using the str_repeat( ) function here would make more sense.
When you embed PHP code in an HTML file, you need to use the .php file extension for that file, so that your web server knows to send the file to PHP for processing. Or, if you have configured your web server to use a different extension for PHP files, use that extension instead.
When you have PHP code embedded in an HTML page, you can think of that page as a PHP program. The bits and pieces of HTML and PHP combine to provide the functionality of the program. A collection of pages that contain programs can be thought of as a web application.
1.3.1 Including Files
An important feature of PHP is its ability to include files. These files may contain additional PHP tags. When you are designing a web application, you can break out common components and place them in a single file. This step makes it much easier to change certain aspects in one place later, and have the change take effect across the entire application. To include a file, use the include keyword:
<?php
$title="My Cool Web Application";
include "header.inc";
?>
The header.inc file might look as follows:
<html><head>
<title><?php echo $title?></title>
</head>
This example illustrates two important concepts of included files in PHP. First, variables set in the including file are automatically available in the included file. Second, each included file starts out in HTML mode. In other words, if you want to include a file that has PHP code in it, you have to embed that code just as you would any other PHP code.
Note also that I used the .inc extension here. This is not a special file type, just an arbitrary extension name I chose. Since your Apache server is not set up to treat .inc files as PHP files, if you put this file somewhere under your document_root, people can browse to it and see the PHP source in that file directly. This is usually not a good idea, so I add these lines to my httpd.conf file:
<Files ~ "\.inc$">
Order allow,deny
Deny from all
</Files>
This blocks any direct access to .inc files.
The other option is to not put the files under document_root, or perhaps to name them .php instead. But be very careful with that last approach. Keep in mind that people will then be able to execute these scripts, when they were probably not designed to be executed in a standalone fashion.
Other ways to include files are through include_once, require, and require_once. The difference between include and require is simply that with include, if the file to be included does not exist, you get a warning, whereas with require you get a fatal error and script execution stops. The include_once and require_once variations ensure that the file being included has not been included already. This helps avoid things like function redefinition errors.
1.4 Language Syntax
Variable names in PHP are case-sensitive. That means $A and $a are two distinct variables. However, function names in PHP are not case-sensitive. This rule applies to both built-in functions and user-defined functions.
PHP ignores whitespace between tokens. You can use spaces, tabs, and newlines to format and indent your code to make it more readable. PHP statements are terminated by semicolons.
There are three types of comments in PHP:
/* C style comments */
// C++ style comments
# Bourne shell style comments
The C++ and Bourne shell-style comments can be inserted anywhere in your code. Everything from the comment characters to the end of the line is ignored. The C-style comment tells PHP to ignore everything from the start of the comment until the end-comment characters. This means that this style of comment can span multiple lines.
1.5 Variables
In PHP, all variable names begin with a dollar sign ($). The $ is followed by an alphabetic character or an underscore, and optionally followed by a sequence of alphanumeric characters and underscores. There is no limit on the length of a variable name. Variable names in PHP are case-sensitive. Here are some examples:
$i
$counter
$first_name
$_TMP
In PHP, unlike in many other languages, you do not have to explicitly declare variables. PHP automatically declares a variable the first time a value is assigned to it. PHP variables are untyped; you can assign a value of any type to a variable.
PHP uses a symbol table to store the list of variable names and their values. There are two kinds of symbol tables in PHP: the global symbol table, which stores the list of global variables, and the function-local symbol table, which stores the set of variables available inside each function.
1.5.1 Dynamic Variables
Sometimes it is useful to set and use variables dynamically. Normally, you assign a variable like this:
$var = "hello";
Now let’s say you want a variable whose name is the value of the $var variable. You can do that like this:
$$var = "World";
PHP parses $$var by first dereferencing the innermost variable, meaning that $var becomes "hello". The expression that’s left is $"hello", which is just $hello. In other words, we have just created a new variable named hello and assigned it the value "World". You can nest dynamic variables to an infinite level in PHP, although once you get beyond two levels, it can be very confusing for someone who is trying to read your code.
There is a special syntax for using dynamic variables, and any other complex variable, inside quoted strings in PHP:
echo "Hello ${$var}";
This syntax also helps resolve an ambiguity that occurs when variable arrays are used. Something like $$var[1] is ambiguous because it is impossible for PHP to know which level to apply the array index to. ${$var[1]} tells PHP to dereference the inner level first and apply the array index to the result before dereferencing the outer level. ${$var}[1], on the other hand, tells PHP to apply the index to the outer level.
Initially, dynamic variables may not seem that useful, but there are times when they can shorten the amount of code you need to write to perform certain tasks. For example, say you have an associative array that looks like:
$array["abc"] = "Hello";
$array["def"] = "World";
Associative arrays like this are returned by various functions in the PHP modules. mysql_fetch_array() is one example. The indices in the array usually refer to fields or entity names within the context of the module you are working with. It’s handy to turn these entity names into real PHP variables, so you can refer to them as simply $abc and $def. This is done as follows:
foreach($array as $index=>$value) {
$$index = $value;
}
1.6 Data Types
PHP provides four primitive data types: integers, floating point numbers, strings, and booleans. In addition, there are two compound data types: arrays and objects.
1.6.1 Integers
Integers are whole numbers. The range of integers in PHP is equivalent to the range of the long data type in C. On 32-bit platforms, integer values range from -2,147,483,648 to +2,147,483,647. PHP automatically converts larger values to floating point numbers if you happen to overflow the range. An integer can be expressed in decimal (base-10), hexadecimal (base-16), or octal (base-8). For example:
$decimal=16;
$hex=0x10;
$octal=020;
1.6.2 Floating Point Numbers
Floating point numbers represent decimal values. The range of floating point numbers in PHP is equivalent to the range of the double type in C. On most platforms, a double can be between 1.7E-308 to 1.7E+308. A double may be expressed either as a regular number with a decimal point or in scientific notation. For example:
$var=0.017;
$var=17.0E-3
PHP also has two sets of functions that let you manipulate numbers with arbitrary precision. These two sets are known as the BC and the GMP functions. See http://www.php.net/bc and http://www.php.net/gmp for more information.
1.6.3 Strings
A string is a sequence of characters. A string can be delimited by single quotes or double quotes:
'PHP is cool'
"Hello, World!"
Double-quoted strings are subject to variable substitution and escape sequence handling, while single quotes are not. For example:
$a="World";
echo "Hello\t$a\n";
This displays “Hello” followed by a tab and then “World” followed by a newline. In other words, variable substitution is performed on the variable $a and the escape sequences are converted to their corresponding characters. Contrast that with:
echo 'Hello\t$a\n';
In this case, the output is exactly “Hello\t$a\n”. There is no variable substitution or handling of escape sequences.
Another way to assign a string is to use what is known as the heredoc syntax. The advantage with this approach is that you do not need to escape quotes. It looks like this:
$foo = <<<EOD
This is a "multiline" string
assigned using the 'heredoc' syntax.
EOD;
The following table shows the escape sequences understood by PHP inside double-quoted strings.
Escape sequence |
Meaning |
\n | Linefeed (LF or 0x0A (10) in ASCII) |
\r | Carriage return (CR or 0x0D (13) in ASCII) |
\t | Horizontal tab (HT or 0x09 (9) in ASCII) |
\\ | Backslash |
\$ | Dollar sign |
\“ | Double quote |
\123 | Octal notation representation of a character |
\x12 | Hexadecimal notation representation of a character |
1.6.4 Booleans
The boolean type only has two states: true and false. For example:
$flag = true;
Boolean values are most commonly used when the == or === operators perform a comparison and return the result.
1.6.5 Arrays
An array is a compound data type that can contain multiple data values, indexed either numerically or with strings. For example, an array of strings can be written like this:
$var[0]="Hello";
$var[1]="World";
Note that when you assign array elements like this, you do not have to use consecutive numbers to index the elements.
As a shortcut, PHP allows you to add an element onto the end of an array without specifying an index. For example:
$var[ ] ="Test";
PHP picks the next logical numerical index. In this case, the "Test" element is given the index 2 in our $var array: if the array has nonconsecutive elements, PHP selects the index value that is one greater than the current highest index value. This autoindexing feature is most useful when dealing with multiple-choice HTML <select> form elements, as we’ll see in a later example.
Although we have called strings a primitive data type, it is actually possible to treat a string as a compound data type, where each character in the string can be accessed separately. In other words, you can think of a string as an array of characters, where the first character is at index 0. Thus, you can pick the third character out of a string with:
$string[2]
To solve an ambiguity problem between strings and arrays, a new syntax has been introduced to dereference individual characters from strings:
$string{2}
This syntax is equivalent to $string[2], and is preferable.
Arrays can also be indexed using strings; these kinds of arrays are called associative arrays:
$var["January"]=1;
$var["February"]=2;
You can use a mix of numerical and string indices with a single array because PHP treats all arrays as hash tables internally, and the hash, or index, can be whatever you want.
All arrays in PHP can be traversed safely with the following mechanism:
foreach($array as $key=>$value) {
echo "array[$key]=$value<br>\n";
}
This is the most common way to loop through each element of an array, whether it is a linear or an associative array. PHP provides a number of array manipulation functions; these are detailed later in the “Function Reference.”
1.6.6 Objects
An object is a compound data type that can contain any number of variables and functions. PHP’s support for objects is somewhat limited in Version 4. PHP Version 5 will improve the object-oriented capabilities of PHP. In PHP 4, the object-oriented support is designed to make it easy to encapsulate data structures and functions in order to package them into reusable classes. Here’s a simple example:
class test {
var $str = "Hello World";
function init($str) {
$this->str = $str;
}
}
$class = new test;
echo $class->str;
$class->init("Hello");
echo $class->str;
This code creates a test object using the new operator. Then it sets a variable called str within the object. In object-speak, a variable in an object is known as a property of that object. The test object also defines a function, known as a method, called init(). This method uses the special-purpose $this variable to change the value of the str property within that object.
Inheritance is supported by using the extends keyword in the class definition. We can extend the previous test class like this:
class more extends test {
function more( ) {
echo "Constructor called";
}
}
This means that the more class inherits from the test class and it also introduces the concept of a constructor. If a method inside a class has the same name as the class, it becomes the constructor function for that class. A constructor is called automatically when the class is instantiated.
Much more information is available at http://www.php.net/oop.
1.6.7 Type Casting
As I already mentioned, you do not need to specify a type when you create a variable, but that doesn’t mean the variables do not have types associated with them. You can explicitly set the type, known as type casting, by using the C-style syntax in which you put the type you want in brackets before the variable or expression. For example:
$var = (int)"123abc";
Without the (int) in this example, PHP creates a string variable. With the explicit cast, however, we have created an integer variable with a value of 123. The following table shows the available cast operators in PHP.
Operators |
Function |
(int), (integer) | Cast to an integer |
(real), (double), (float) | Cash to a floating point number |
(string) | Cast to a string |
(array) | Cast to an array |
(object) | Cast to an object |
(bool), (boolean) | Cast to a boolean |
(unset) | Cast to NULL; the same as calling unset( ) on the value |
Although they are not usually needed, PHP does provide the following built-in functions to check variable types in your program: gettype(), is_bool(), is_long(), is_float(), is_string(), is_array(), and is_object().
1.7 Expressions
An expression is the basic building block of the language. Anything with a value can be thought of as an expression. Examples include:
5
5+5
$a
$a==5
sqrt(9)
By combining many of these basic expressions, you can build larger, more complex expressions.
Note that the echo statement we’ve used in numerous examples cannot be part of a complex expression because it does not have a return value. The print statement, on the other hand, can be used as part of complex expression — it does have a return value. In all other respects, echo and print are identical: they output data.
1.8 Operators
Expressions are combined and manipulated using operators. The following table lists the operators from highest to lowest precedence; the second column (A) shows the operators’ associativity. These operators should be familiar to you if you have any C, Java, or Perl experience.
Operators |
A |
!, ~, ++, --, @, (the casting operators) | Right |
*, /, % | Left |
+, -, . | Left |
<<, >> | Left |
<, <=, >=, > | Nonassociative |
==, !=, ===, !== | Nonassociative |
& | Left |
^ | Left |
| | Left |
&& | Left |
|| | Left |
? : (conditional operator) | Left |
=, +=, -=, *=, /=, %=, ^=, .=, &=, |=, <<=, >>= | Left |
AND | Left |
XOR | Left |
OR | Left |
1.9 Control Structures
The control structures in PHP are very similar to those used by the C language. Control structures are used to control the logical flow through a PHP script. PHP’s control structures have two syntaxes that can be used interchangeably. The first form uses C-style curly braces to enclose statement blocks, while the second style uses a more verbose syntax that includes explicit ending statements. The first style is preferable when the control structure is completely within a PHP code block. The second style is useful when the construct spans a large section of intermixed code and HTML. The two styles are completely interchangeable, however, so it is really a matter of personal preference which one you use.
1.9.1 if
The if statement is a standard conditional found in most languages. Here are the two syntaxes for the if statement:
if(expr) { if(expr):
statements statements
} elseif(expr) { elseif(expr):
statements statements
} else { else:
statements statements
} endif;
The if statement causes particular code to be executed if the expression it acts on is true. With the first form, you can omit the braces if you only need to execute a single statement.
1.9.2 switch
The switch statement can be used in place of a lengthy if statement. Here are the two syntaxes for switch:
switch(expr) { switch(expr):
case expr: case expr:
statements statements
break; break;
default: default:
statements statements
break; break;
} endswitch;
The expression for each case statement is compared against the switch expression and, if they match, the code following that particular case is executed. The break keyword signals the end of a particular case; it may be omitted, which causes control to flow into the next case. If none of the case expressions match the switch expression, the default case is executed.
1.9.3 while
The while statement is a looping construct that repeatedly executes some code while a particular expression is true:
while(expr) { while(expr):
statements statements
} endwhile;
The while expression is checked before the start of each iteration. If the expression evaluates to true, the code within the loop is executed. If the expression evaluates to false, however, execution skips to the code immediately following the while loop. Note that you can omit the curly braces with the first form of the while statement if you only need to execute a single statement.
It is possible to break out of a running loop at any time using the break keyword. This stops the current loop and, if control is within a nested set of loops, the next outer loop continues. It is also possible to break out of many levels of nested loops by passing a numerical argument to the break statement (break n) that specifies the number of nested loops it should break out of. You can skip the rest of a given loop and go onto the next iteration by using the continue keyword. With continue n, you can skip the current iterations of the n innermost loops.
1.9.4 do/while
The do/while statement is similar to the while statement, except that the conditional expression is checked at the end of each iteration instead of before:
do {
statements
} while(expr);
Note that due to the order of the parts of this statement, there is only one valid syntax. If you only need to execute a single statement, you can omit the curly braces from the syntax. The break and continue statements work with this statement in the same way that they do with the while statement.
1.9.5 for
A for loop is a more complex looping construct than the simple while loop:
for(start_expr; cond_expr; iter_expr) {
statements
}
for(start_expr; cond_expr; iter_expr):
statements
endfor;
A for loop takes three expressions. The first is the start expression; it is evaluated once when the loop begins. This is generally used for initializing a loop counter. The second expression is a conditional expression that controls the iteration of the loop. This expression is checked prior to each iteration. The third expression, the iterative expression, is evaluated at the end of each iteration and is typically used to increment the loop counter. With the first form of the for statement, you can omit the braces if you only need to execute a single statement.
The break and continue statements work with a for loop like they do with a while loop, except that continue causes the iterative expression to be evaluated before the loop conditional expression is checked.
1.9.6 foreach
A foreach loop is used to loop through an array. Here are both forms of the syntax:
foreach(array_expression as $value) {
statements
}
foreach(array_expression as $value):
statements
endforeach;
This loops through the array_expression and assigns each value of the array to $value in turn. You can also get the key for each element with this syntax:
foreach(array_expression as $key=>$value) {
statements
}
The break and continue statements work with a foreach loop like they do with a for loop.
.10 Functions
A function is a named sequence of code statements that can optionally accept parameters and return a value. A function call is an expression that has a value; its value is the returned value from the function. PHP provides a large number of internal functions. The “Function Reference” section lists all of the commonly available functions. PHP also supports user-definable functions. To define a function, use the function keyword. For example:
function soundcheck($a, $b, $c) {
return "Testing, $a, $b, $c";
}
When you define a function, be careful what name you give it. In particular, you need to make sure that the name does not conflict with any of the internal PHP functions. If you do use a function name that conflicts with an internal function, you get the following error:
Fatal error: Can't redeclare already declared function in
filename on line N
After you define a function, you call it by passing in the appropriate arguments. For example:
echo soundcheck(4, 5, 6);
You can also create functions with optional parameters. To do so, you set a default value for each optional parameter in the definition, using C++ style. For example, here’s how to make all the parameters to the soundcheck() function optional:
function soundcheck($a=1, $b=2, $c=3) {
return "Testing, $a, $b, $c";
}
1.10.1 Passing Arguments to Functions
There are two ways you can pass arguments to a function: by value and by reference. To pass an argument by value, you pass in any valid expression. That expression is evaluated and the value is assigned to the corresponding parameter defined within the function. Any changes you make to the parameter within the function have no effect on the argument passed to the function. For example:
function triple($x) {
$x=$x*3;
return $x;
}
$var=10;
$triplevar=triple($var);
In this case, $var evaluates to 10 when triple() is called, so $x is set to 10 inside the function. When $x is tripled, that change does not affect the value of $var outside the function.
In contrast, when you pass an argument by reference, changes to the parameter within the function do affect the value of the argument outside the scope of the function. That’s because when you pass an argument by reference, you must pass a variable to the function. Now the parameter in the function refers directly to the value of the variable, meaning that any changes within the function are also visible outside the function. For example:
function triple(&$x) {
$x=$x*3;
return $x;
}
$var=10;
triple($var);
The & that precedes $x in the triple() function definition causes the argument to be passed by reference, so the end result is that $var ends up with a value of 30.
1.10.2 Variable Scope
The scope of a variable is the context within which a variable is available. There are two scopes for variables in PHP. Global variables are available directly from the mainline PHP execution. That is, if you are not inside a function, you can access global variables directly. Unlike most other languages, functions in PHP have their own, completely separate variable scope. Take this example:
<?php
function test( ) {
echo $a;
}
$a = "Hello World";
test( );
?>
If you run this script you will find that there is no output. This is because the $a you are trying to access inside the test( ) function is a completely different variable from the global $a you created in the global scope just before calling the function. In order to access a globally-scoped variable from inside a function, you need to tell the function to use the global scope for that particular variable. It can be done with the global keyword like this:
<?php
function test( ) {
global $a;
echo $a;
}
$a = "Hello World";
test( );
?>
Alternatively, you can use the $GLOBALS array like this:
<?php
function test( ) {
echo $GLOBALS['a'];
}
$a = "Hello World";
test( );
?>
In this last example, the $GLOBALS array is known as a superglobal, which is a variable that is automatically available in all scopes without needing to be declared global in order to be accessed from within a function.
1.10.3 Static Variables
PHP supports declaring local function variables as static. A static variable retains its value between function calls, but is still accessible only from within the function it is declared in. Static variables can be initialized; this initialization only takes place the first time the static declaration is executed. Static variables are often used as counters, as in this example:
function hitcount( )
static $count = 0;
if ($count == 0) {
echo "This is the first access to this page";
} else {
echo "This page has been accessed $count times";
}
$count++;
}
1.11 Web-Related Variables
PHP automatically creates variables for all the data it receives in an HTTP request. This can include GET data, POST data, cookie data, and environment variables. The variables are either in PHP’s global symbol table or in one of a number of superglobal arrays, depending on the value of the register_globals setting in your php.ini file.
In PHP 4.2.0 and after, the default setting for register_globals is off. With register_globals off, all the various variables that are usually available directly in the global symbol table are now available via individual superglobal arrays. There is a limited set of superglobals and they cannot be created from a user-level script. The superglobal array to use depends on the source of the variable. Here is the list:
$_GET
GET-method variables. These are the variables supplied directly in the URL. For example, with http://www.example.com/script.php?a=1&b=2, $_GET['a'] and $_GET['b'] are set to 1 and 2, respectively.
$_POST
POST-method variables. Form field data from regular POST-method forms.
$_COOKIE
Any cookies the browser sends end up in this array. The name of the cookie is the key and the cookie value becomes the array value.
$_REQUEST
This array contains all of these variables (i.e., GET, POST, and cookie). If a variable appears in multiple sources, the order in which they are imported into $_REQUEST is given by the setting of the variables_order php.ini directive. The default is 'GPC', which means GET-method variables are imported first, then POST-method variables (overriding any GET-method variables of the same name), and finally cookie variables (overriding the other two).
$_SERVER
These are variables set by your web server. Traditionally things like DOCUMENT_ROOT, REMOTE_ADDR, REMOTE_PORT, SERVER_NAME, SERVER_PORT, and many others. To get a full list, have a look at your phpinfo( ) output, or run a script like the following to have a look:
<?php
foreach($_SERVER as $key=>$val) {
echo '$_SERVER['.$key."] = $val<br>\n";
}
?>
$_ENV
Any environment variables that were set when you started your web server are available in this array.
$_FILES
For RFC 1867-style file uploads the information for each uploaded file is available in this array. For example, for a file upload form containing:
<input name="userfile" type="file">
The $_FILES array will look something like this:
$_FILES['userfile']['name'] => photo.png
$_FILES['userfile']['type'] => image/png
$_FILES['userfile']['tmp_name'] => /tmp/phpo3kdGt
$_FILES['userfile']['error'] => 0
$_FILES['userfile']['size'] => 158918
Note that the 'error' field is new for PHP 4.2.0 and the values are: 0 (no error, file was uploaded); 1 (the uploaded file exceeds the upload_max_filesize directive in php.ini); 2 (the uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form); 3 (the actual number of bytes uploaded was less than the specified upload file size); and 4 (no file was uploaded).
1.12 Sessions
Sessions are used to help maintain the values of variables across multiple web pages. This is done by creating a unique session ID that is sent to the client browser. The browser then sends the unique ID back on each page request and PHP uses the ID to fetch the values of all the variables associated with this session.
The session ID is sent back and forth in a cookie or in the URL. By default, PHP tries to use cookies, but if the browser has disabled cookies, PHP falls back to putting the ID in the URL. The php.ini directives that affect this are:
session.use_cookies
When on, PHP will try to use cookies
session.use_trans_sid
When on, PHP will add the ID to URLs if cookies are not used
The trans_sid code in PHP is rather interesting. It actually parses the entire HTML file and modifies/mangles every link and form to add the session ID. The url_rewriter.tags php.ini directive can change how the various elements are mangled.
Writing an application that uses sessions is not hard. You start a session using session_start( ), then register the variables you wish to associate with that session. For example:
<?php
session_start( );
session_register('foo');
session_register('bar');
$foo = "Hello";
$bar = "World";
?>
If you put the previous example in a file named page1.php and load it in your browser, it sends you a cookie and stores the values of $foo and $bar on the server. If you then load this page2.php page:
<?php
session_start( );
echo "foo = $_SESSION[foo]<br />";
echo "bar = $_SESSION[bar]<br />";
?>
You should see the values of $foo and $bar set in page1.php. Note the use of the $_SESSION superglobal. If you have register_globals on, you would be able to access these as $foo and $bar directly.
You can add complex variables such as arrays and objects to sessions as well. The one caveat with putting an object in a session is that you must load the class definition for that object before you call session_start( ).
A common error people make when using sessions is that they tend to use it as a replacement for authentication — or sometimes as an add-on to authentication. Authenticating a user once as he first enters your site and then using a session ID to identify that user throughout the rest of the site without further authentication can lead to a lot of problems if another person is somehow able to get the session ID. There are a number of ways to get the session ID:
- If you are not using SSL, session IDs may be sniffed
- If you don’t have proper entropy in your session IDs, they may be guessed
- If you are using URL-based session IDs, they may end up in proxy logs
- If you are using URL-based session IDs, they may end up bookmarked on publicly-accessible computers
Forcing HTTP Authentication on each page over SSL is the most secure way to avoid this problem, but it tends to be a bit inconvenient. Just keep the above points in mind when building a web application that uses sessions to store users’ personal details.
1.13 Examples
The best way to understand the power of PHP is to examine some real examples of PHP in action, so we’ll look at some common uses of PHP in this section.
1.13.1 Showing the Browser and IP Address
Here is a simple page that prints out the browser string and the IP address of the HTTP request. Create a file with the following content in your web directory, name it something like example.php3, and load it in your browser:
<html><head><title>PHP Example</title></head>
<body>
You are using
<?php echo $_SERVER['HTTP_USER_AGENT'] ?>
<br />
and coming from
<?php echo $_SERVER['REMOTE_ADDR'] ?>
</body></html>
You should see something like the following in your browser window:
You are using Mozilla/5.0 (X11; U; Linux i686; en-US;
rv:1.1b) Gecko/20020722
and coming from 127.0.0.1
1.13.2 Intelligent Form Handling
Here is a slightly more complex example. We are going to create an HTML form that asks the user to enter a name and select one or more interests from a selection box. We could do this in two files, where we separate the actual form from the data handling code, but instead, this example shows how it can be done in a single file:
<html><head><title>Form Example</title></head>
<body>
<h1>Form Example</h1>
<?
function show_form($first="", $last="",
$interest="") {
$options = array("Sports", "Business", "Travel",
"Shopping", "Computers");
if(!is_array($interest)) $interest = array( );
?>
<form action="form.php" method="POST">
First Name:
<input type="text" name="first"
value="<?echo $first?>">
<br />
Last Name:
<input type="text" name="last"
value="<?echo $last?>">
<br />
Interests:
<select multiple name="interest[ ]">
<?php
foreach($options as $option) {
echo "<option";
if(in_array($option, $interest)) {
echo " selected ";
}
echo "> $option</option>\n";
}
?>
</select><br />
<input type=submit>
</form>
<?php } // end of show_form( ) function
if($_SERVER['REQUEST_METHOD']!='POST') {
show_form( );
} else {
if(empty($_POST['first']) ||
empty($_POST['last']) ||
empty($_POST['interest'])) {
echo "<p>You did not fill in all the fields,";
echo "please try again</p>\n";
show_form($_POST['first'],$_POST['last'],
$_POST['interest']);
}
else {
echo "<p>Thank you, $_POST[first] $_POST[last], you ";
echo 'selected '.
join(' and ', $_POST['interest']);
echo " as your interests.</p>\n";
}
}
?>
</body></html>
There are a few things to study carefully in this example. First, we have isolated the display of the actual form to a PHP function called show_form(). This function is intelligent, in that it can take the default value for each of the form elements as an optional argument. If the user does not fill in all the form elements, we use this feature to redisplay the form with whatever values the user has already entered. This means the user only has to fill the fields he missed, which is much better than asking the user to hit the Back button or forcing him to reenter all the fields.
Notice how the file switches back and forth between PHP code and HTML. Right in the middle of defining our show_form() function, we switch back to HTML to avoid having numerous echo statements that just echo normal HTML. Then, when we need a PHP variable, we switch back to PHP code temporarily, just to print the variable.
We’ve given the multiple-choice <select> element the name interest[ ]. The [ ] on the name tells PHP that the data coming from this form element should be treated as an auto-indexed array. This means that PHP automatically gives each element the next sequential index, starting with 0 (assuming the array is empty to begin with).
The final thing to note is the way we determine what to display. We check if the SERVER variable REQUEST_METHOD is set to POST. If it isn’t, we know that the user has not submitted the form yet, so we call show_form() without any arguments. This displays the empty form. If $first is set, however, we check to make sure that the $first and $last text fields are not empty and that the user has selected at least one interest.
1.13.3 Web Database Integration
To illustrate a complete database-driven application, we are going to build a little web application that lets people make suggestions and vote on what you should name your new baby. The example uses MySQL, a fast and easy to configure database (see http://www.mysql.com), but it can be changed to run on any of the databases that PHP supports.
The schema for our baby-name database looks like this:
CREATE TABLE baby_names (
name varchar(30) NOT NULL,
votes int(4),
PRIMARY KEY (name)
);
This is in MySQL’s query format and can be used directly to create the actual table. It simply defines a text field and an integer field. The text field is for the suggested baby name and the integer field is for the vote count associated with that name. We are making the name field a primary key, which means uniqueness is enforced, so that the same name cannot appear twice in the database.
We want this application to do a number of things. First, it should have a minimal check that prevents someone from voting many times in a row. We do this using a session cookie. Second, we want to show a fancy little barchart that depicts the relative share of the votes that each name has received. The barchart is created using a one pixel by one pixel blue dot GIF image and scaling the image using the height and width settings of the HTML <img> tag. We could also use PHP’s built-in image functions to create a fancier-looking bar.
Everything else is relatively straightforward form and database work. We use a couple of shortcuts as well. For example, instead of reading all the entries from the database and adding up the votes in order to get a sum (which we need to calculate the percentages), we ask MySQL to do it for us with its built-in sum( ) function. The part of the code that displays all the names and their votes along with the percentage bar gets a little ugly, but you should be able to follow it. We are simply sending the correct HTML table tags before and after the various data we have fetched from the database.
Here’s the full example:
<?
if($vote && !$already_voted)
SetCookie('already_voted',1);
?>
<html><head><title>Name the Baby</title>
</head><h3>Name the Baby</h3>
<form action="baby.php" method="POST">
<p>Suggestion:
<input type="text" name="new_name"></p>
<input type="submit"
value="Submit idea and/or vote">
<?
mysql_pconnect("localhost","","");
$db = "test";
$table = "baby_names";
if($new_name) {
if(!mysql_db_query($db, "insert into $table
values ('$new_name',0)")) {
echo mysql_errno( ).': '.
mysql_error( )."<br />\n";
}
}
if($vote && $already_voted) {
echo '<p><b>Hey, you voted already ';
echo "Vote ignored.</b></p>\n";
}
else if($vote) {
if(!mysql_db_query($db,
"update $table set votes=votes+1
where name='$vote'")) {
echo mysql_errno( ).': '.
mysql_error( )."<br />\n";
}
}
$result=mysql_db_query($db,
"select sum(votes) as sum from $table");
if($result) {
$sum = (int) mysql_result($result,0,"sum");
mysql_free_result($result);
}
$result=mysql_db_query($db,
"select * from $table order by votes DESC");
echo <<<EOD
<table border="0"><tr><th>Vote</th>
<th>Idea</th><th colspan="2">Votes</th>
</tr>
EOD;
while($row=mysql_fetch_row($result)) {
echo <<<FOO
<tr><td align="center">
<input type="radio"
name="vote" value="$row[0]"></td>
<td>$row[0]</td>
<td align="right">$row[1]</td>
<td>
FOO;
if($sum && (int)$row[1]) {
$per = (int)(100 * $row[1]/$sum);
echo '<img src="bline.gif" height=12 ';
echo "width=$per> $per %</td>";
}
echo "</tr>\n";
}
echo "</table>\n";
mysql_free_result($result);
?>
<input type="submit"
value="Submit idea and/or vote" />
<input type="reset" />
</form>
</body></html>