A Brief Introduction to PHP
This page is meant to cover the basic concepts needed to create dynamic web pages using PHP with a focus on accessing PostgreSQL databases. A thorough description of all the capabilities of PHP is far beyond the scope of this document, so links have been provided throughout the page to sites with further information on various topics. For an in-depth tutorial on PHP, see the PHP home page or one of the many books on the subject -- recommended is Leon Atkinson's Core PHP Programming, from which some of this document has been adapted.
What is PHP?
PHP (which stands for "PHP: Hypertext Preprocessor") is an open-source server-side scripting language which can be embedded within HTML. When a page with PHP code embedded in it is requested from a PHP-enabled web server, the PHP code is interpreted prior to display of the page, allowing dynamic creation of the HTML page provided to the browser while hiding the script itself from display. For this class, an Apache web server has been set up with PHP installed as a module, allowing PHP scripts to be interpreted without the spawning of additional processes on the web server. This page actually uses PHP -- the color highlighting of the code examples is done with a PHP function called show_source. The example pages linked to from this page are all written entirely in PHP and have links to their complete source code; several functions are included on each page to simplify the creation of repeated elements on the pages, and their source can be seen here.
A first look at a PHP script
PHP is embedded in web pages by the use of a special HTML tag, <? ?>. When a page with the correct extension (typically .php) is requested by a browser, the text enclosed within the ? tags is interpreted and replaced with any output created by the script. The resulting page is then passed to the browser as regular HTML.
So, a page containing this:
<HTML>
<BODY>
<H1>A PHP-enabled web page</H1>
<? print("This page uses PHP!"); ?>
</BODY>
</HTML>
will send this to a web browser when requested:
<HTML>
<BODY>
<H1>A PHP-enabled web page<H1>
This page uses PHP!
</BODY>
</HTML>
Click here to see this page in action
The Basics of the PHP Language
PHP is a full-fledged programming language, similar to C syntactically but very loosely typed. It has many built-in functions to simplify web page creation, including an especially broad range of functions for database access, along with the capability for either procedural or object-oriented programming. This section outlines the basic constructs of the language and provides working examples to illustrate many of its features.
Source code structure
PHP ignores whitespace, including carriage returns -- each statement must end with a semicolon. Multiline comments may be created by enclosing them within /* */ as in C; in addition, anything following # or // on a line is interpreted as a comment.
Operators
The operators in PHP are essentially identical to those in C; all the arithmetic and assignment operators, including special operators such as ++ and *=, are included, along with logical and bitwise operators. A few notable additions include the . operator for concatenation of strings and the @ operator to suppress function errors.
Variables
All variables in PHP are preceded by $ (which is actually considered by the PHP interpreter to be an operator for variable reference); they do
Control Structures
Flow-of-execution control statements in PHP are C-like in their syntax and include if-elseif-else (and its abbreviated form ?: ), switch/case, while, do..while, and for. The break statement is used to exit a control loop; PHP also provides an exit statement which prevents anything further, including HTML outside PHP tags, from being sent to the browser.
Functions
Functions, unlike variables, must be declared before they are called.
An example will demonstrate many of the features of functions in PHP:
<?
function FormatText($text, $color="black") {
global $fontsize;
static $linecount;
/* Backslashes are needed to keep the double quotes from
being interpreted by PHP.*/
print("<FONT COLOR=\"$color\" SIZE=\"$fontsize\">$text</FONT>");
print("<BR><BR>");
$linecount++;
print("This function has displayed $linecount lines.<BR>");
print("<BR><BR>");
}
$fontsize = 24;
$text = "This is a text string";
FormatText($text);
?>
This function will take a line of text and an optional color and display the text in the given color (or black if none is supplied) and a fontsize set in a global variable. A static variable is maintained between calls to the function to count the number of lines displayed. Note that color must be the last variable in the list of arguments, since it is optional. Providing a default value is all that is required to make an argument optional, but all optional arguments must be after any required arguments, since the arguments are matched by their positions in the function call.
This function could also have been written:
<?
function FormatText($text, &$linecount, $color="black") {
global $fontsize;
print("<FONT COLOR=\"$color\">$text</FONT>");
$linecount++;
}
?>
Here, $linecount is a variable from outside the scope of the function that has been passed as an argument instead of a static variable within the function; its value can be updated from within the function because the & before the variable name in the list of arguments indicates that it is to be passed by reference instead of by value.
Suppose you instead wanted to just return the string to the main program. It could be a global variable or passed by reference, as in the examples above, or it could be a return value:
<?
function FormatText($text, $color="black") {
global $fontsize;
$changedline = "<FONT COLOR=\"$color\">$text</FONT>");
return($changedline);
}
$line=FormatText($line);
print("$line");
?>
Click here to see a working example using this function
PHP also allows dynamic function calls (setting the value of a variable to be the name of a function and then calling the variable as if it were the function) and recursive function calls.
Arrays
PHP provides both integer-indexed and associative array functionalities similar to those available in Perl. Elements may be added by assignment; in an integer-indexed array, assigning to an array without specifying an index will automatically assign the first available index after the last used index. For example, these two sections of code produce identical arrays:
<?
$Days[0]="Sunday";
$Days[1]="Monday";
?>
<?
$Days[]="Sunday";
$Days[]="Monday";
?>
Traversing Arrays
Integer-indexed arrays can be easily traversed with a
<?
$maxindex= count($Days); // The count function returns the number of array elements
for($i=0; $i < $maxindex; $i++) {
print("$Days[$i]");
}
?>
For associative arrays, several functions are provided to allow easy traversal based on the fact that each array keeps an internal pointer to a "current" element:
<?
$Info["Name"]="Jane Doe";
$Info["Age"]=21;
$Info["Hometown"]="Knoxville";
/* The reset function resets the pointer to the first element of the array,
key gets the current key, and next moves the pointer ahead one element;
when the pointer is moved past the end of the array, key($Info) will
return null and end the for loop. */
for(reset($Info); $current = key($Info); next($Info)) {
$value = pos($Info) // The pos function returns the value of the current array element
print ("$key is $value.<BR>");
}
?>
Another way to traverse an associative array is with the each function:
<?
$Info["Name"]="Jane Doe";
$Info["Age"]=21;
$Info["Hometown"]="Knoxville";
/* The each function creates a four-element array with the key in two elements with keys 0 and key and the value in two elements with keys 1 and value */
while($Item=each($Info))
{
print($Item[0]);
print($Item[1]);
print($Item['key']);
print($Item['value']);
}
?>
These array traversal functions give PHP great programming flexibility,
as they allow associative arrays to be used as a kind of linked list.
Click here to see the above code in action
Initializing ArraysThe array function is used to fill multiple values into an array at once to avoid the need for multiple assignment statements. An index may be assigned for each value or a beginning integer index may be given so that following elements will be assigned indices in numeric order. For example:
<? $PeopleArray = array(1=>"Bob","Carol","Ted","Alice"); ?>
<? $PeopleArray = array("Smith"=>"Bob","Jones"=>"Carol","Williams"=>"Ted","Johnson"=>"Alice"); ?>
are both valid uses of the array function.
Multidimensional Arrays
Multidimensional arrays may be created as either integer-indexed or associative arrays or a mixture of both. For example, this is a valid use of the array function:
<?
$PeopleArray = array("Smiths"=>array("Bob","Sue"), "Johnsons"=>array("Alice","John"));
print($PeopleArray["Smiths"][1]);
?>
Other Useful Array Functions
Often you may want to split a delimited string into an array for manipulation or pack an array into a delimited string to write out to a file. In PHP, this is accomplished with the explode and implode functions:
<?
$text = "Jane Doe|21|Knoxville";
$info = explode("|",$text);
for($i=0; $i < count($info); $i++) {
print($info[$i]);
}
$newtext = implode($info,";");
print($newtext);
?>
Click here to see the above examples in action
PHP also provides functions to find the maximum or minimum value in an array (max($arrayname) and min($arrayname)), sort by keys (ksort($arrayname)), sort an integer-indexed array by values (sort($arrayname)), sort an associative array by values (asort($arrayname)), and execute a function on each element of an array (array_walk($arrayname,functionname)).
I/O
Browser Output
Obviously we need to be able to output information to the browser to make PHP useful. Three functions are provided for this: echo, print (which several examples have already used), and printf.
The
<?
echo "This"," ","is"," ","a"," ","string.";
?>
The
<?
$word = "string";
print("This is a $word.");
?>
The
<?
$number = 2.3;
printf("%2.5d",$number);
?>
Click here to see a page with these examples
File OperationsPHP provides many of the same functions for file I/O as C, including fopen, fclose, fgetc, fgets, and feof. The default current directory for relative paths is the directory in which the script is located, but this can be changed with the chdir function.
Some additional file I/O functions in PHP include file, which reads an entire file into an array one line per element, file_exists, which takes a file name and returns 1 if the file exists, and fpassthru, which displays an entire file directly to the browser. Most file I/O functions also have corresponding gz functions designed to operate on gnuzip-compressed files, e.g. gzopen.
Click here to see examples of file I/O functions
User InputTo be able to create a useful application, we need to be able to accept user input. This is usually done through the use of HTML forms. When a user fills in a form on a web page and submits it, the script specified in the FORM ACTION tag is called to act on the collected information. For example, consider a page with two fields, name and birthdate, which then calls a script to calculate the user's age in days. The first page might look like this:
<HTML>
<BODY>
<FORM ACTION="days.php" METHOD="post">
Name:
<INPUT TYPE="text" NAME="name"><BR>
Birthdate:
<INPUT TYPE="text" NAME="birthdate"><BR>
<INPUT TYPE="submit">
</FORM>
</BODY>
</HTML>
The file days.php would then contain the script to do the calculation and display the result:
<?
$today = mktime();
/* The mktime function creates a timestamp out of a given time
expressed as (hours,minutes,seconds,month,day,year) */
$BdayArray=explode("/",$birthdate);
$stamp = mktime(0,0,0,$BdayArray[0],$BdayArray[1],$BdayArray[2]);
$difference = $today - $stamp;
/* Since dates are represented in seconds since the epoch,
the difference of two dates is in seconds, so we divide by
86400 to get days. */
$difference = $difference/86400;
print("$name, you are ");
printf("%d",$difference);
print(" days old.");
?>
Click here to see working pages with this example
Note that the form inputs are automatically transformed into variables in the script with names matching the NAME attributes of the fields on the HTML page. This only works if the "register globals" option has been enabled in php.ini. This is NOT recommended on production systems. See Variables from outside PHP for information on how to use POST/GET forms without "register globals".
Database Access
PHP has built-in functions for accessing a large number of specific databases (dBase, DBM, FilePro, Informix, Ingres II, Interbase, mSQL, MySQL, Oracle, PostgreSQL, Sybase, and Velocis, to name a few) and ODBC support as well as "database" access functions for IMAP, LDAP, and SNMP. This section will cover only PostgreSQL functions; full references for all the database functions can be found at php.net.
The following example shows the use of some of the most common PHP PostgreSQL functions:
<?
$connection = pg_connect("host=dbs.cs.utk.edu user=example
password=password dbname=testdb");
$query = "SELECT * FROM testtable";
/* The pg_exec function executes, on the connection represented by the
first argument, the query in the string given as the second argument.
The return value is an identifier pointing to the result set
for the query. */
$result = pg_exec($connection, $query);
/* The pg_numfields function returns the number of fields in a result set. */
print("There are ");
print(pg_numfields($result));
print(" fields in the testtable.<P>");
/* The pg_fieldname function returns the name of a field in a result
set based on the index of that field (returned fields are automatically
assigned indices from 0 to 1 less than the number of fields returned). */
print("The fields are: <BR>");
for($i=0;$i<pg_numfields($result);$i++) {
print(pg_fieldname($result,$i));
print("<BR>");
}
/* The pg_numrows function returns the number of rows in a record set*/
print("The testtable has ");
print(pg_numrows($result));
print(" rows.<BR>");
/* The pg_fieldisnull function returns 1 if the specified field in
the specified row is NULL. */
if(pg_fieldisnull($result,0,0)) {
print("The first field of the first row is null.<BR>");
}
else {
print("The first field of the first row is not null.<BR>");
}
/* The pg_fetch_array function returns an array containing each field
for the specified row indexed by both number and fieldname; note
that if you only need the fields indexed by number, you can use the
pg_fetch_row function with the same arguments */
$rowarray=pg_fetch_array($result,0);
print("The first field of the first row contains: $rowarray[0]<BR>");
/* If you only need to find the value of a particular field in a
particular row, you can also use the pg_result function */
$fieldval = pg_result($result,0,0);
print("The first field of the first row still contains: ");
print("$fieldval<BR>");
/* The pg_errormessage function returns the error message for the
last database access */
$errstring = pg_errormessage($connection);
if((strlen($errstring))==0) {
print("The call to pg_result was successful.<BR>");
}
else {
print("Pg_result returned the following error message: $errstring<BR>");
}
/* The pg_freeresult function frees the memory allocated for the
given result set. */
pg_freeresult($result);
/* The pg_close function closes the given connection. */
pg_close($connection);
?>
Click here to see the above code in action
The functions in the above example are by no means the only PHP PostgreSQL functions; see the PHP manual for complete descriptions of all the available functions.
Web Page Design
This section will cover some useful techniques for the creation of complex web sites with PHP -- many more ideas can be found at sites like
http://www.phpbuilder.com. File InclusionMany web sites have elements that repeat on each page of the site, such as navigation bars or ad banners.
A large site can become very difficult to maintain if the code for such items has to be changed on each page,
so PHP provides two ways to include a file into a page, thus allowing repeated elements to be kept in a single
file: include and require. Each takes a filename as an argument, but their behavior is slightly different. A call to
the
Not all browsers work exactly the same -- a page that looks great in Netscape may look terrible in Internet Explorer or vice versa, or a page that looks fine in Netscape on a Windows 98 machine may not look right in Netscape on a Linux machine. You can code around such problems when you find them by using the HTTP_USER_AGENT variable, which is automatically set when a browser makes a request of a server. For example, here's what HTTP_USER_AGENT is set to for your browser:
CCBot/1.0 (+http://www.commoncrawl.org/bot.html)
A good way to make use of the information provided by this variable is to compare the value of the variable to some string using the strstr function:
<?
if(strstr($HTTP_USER_AGENT,"MSIE")) {
print "Your browser is Internet Explorer"
}
else {
print "Your browser is not Internet Explorer"
}
?>
Click here to see a working version of this example
Passing information between pages
<?
$testvar = "This is a test";
/* The urlencode function translates special characters such as spaces
so that they will be passed through to the page correctly. */
echo "<A HREF=\"ex10.php?testvar=",urlencode($testvar),
"\">Another Test Page</A>";
?>
And ex10.php looked like this:
<?
print $testvar;
?>
Then when you clicked on the link, the page would say "This is a test."
Cookies are information sent from the server to the browser to be stored, and are often used to save
information on a user's computer, such as what pages at a site a user has visited or the session identifier
assigned to a user's current login at a site. To set a cookie, use the setcookie function, which must be called
before any other information is sent to the browser.