Alternative Development Environments

 < Day Day Up > 

Developing Web Applications Using PHP

PHP (PHP Hypertext Preprocessor it's recursive) is a relatively new language that integrates with the Apache web server. Whereas Perl is a general-purpose programming language, PHP provides web-specific functions that can speed up development time significantly.

One of the primary differences between Perl and PHP is how it is programmed. With Perl, the focus is on the application logic; integrating an interface is secondary. When using PHP, the logic is embedded into the HTML. Yes, there are means of writing embedded Perl, but the PHP language itself was designed to be used in this fashion from the start.

A PHP developer can use traditional web development tools, such as Macromedia Dreamweaver MX or Adobe GoLive, to create an interface and then attach logic. For example, in Perl, we used code like this to print a variable within some HTML:

 print <<HTML;     print "<tr>";     print "<td align=\"center\">$myname</td>";     print "</tr>"; HTML 

The equivalent code in PHP looks like this:

 <tr> <td align="center"><?php print $myname; ?></td> </tr> 

As you can see, the application code is entirely isolated from the HTML. PHP code is contained with its own tags: <?php to start and ?> to end. As Apache reads a PHP file, it executes the code in the PHP tags and then sends the final result to the waiting browser. The remote user cannot see these special tags in the HTML source your application logic is safe from prying eyes. In addition to a clean programming model, PHP offers features such as built-in database access, advanced security, and real-time graphic generation.

Enabling the PHP Module in Apache

Your Tiger system comes with a fully functioning version of PHP installed. Activating it is simply a matter of changing a few lines in the /etc/httpd/httpd.conf file. Open the file, and look for the following lines:

 #LoadModule php4_module    libexec/httpd/libphp4.so #AddModule mod_php4.c 

These lines are noncontiguous in the configuration file they're shown together here to save space. Activate PHP by uncommenting each line (removing the #).

Restarting Apache with sudo /usr/sbin/apachectl restart will active your PHP module.

To fine-tune the PHP configuration, you'll need to install a PHP .ini file in /etc/php.ini. Apple has included the file /etc/php.ini.default on your system. Copy this file to /etc/php.ini, and then open it in your text editor of choice.

First, make sure that any system-specific settings are set. The default settings usually work perfectly fine. You might want to look at the resource settings, however, because they can be used to make sure that renegade scripts don't eat up the memory and CPU time on your system. Look in the php.ini for these lines:

 ;;;;;;;;;;;;;;;;;;; ; Resource Limits ; ;;;;;;;;;;;;;;;;;;; max_execution_time = 30  ; Maximum execution time of each script, in seconds memory_limit = 8M     ; Maximum amount of memory a script may consume (8MB) 

By default, scripts can use up to 8MB of memory and take 30 seconds to execute. For many CGIs, these are rather liberal values. You can reduce them as you want; I've cut them in half on my system and haven't had any problems thus far.

Additionally, you should enable safe mode (safe_mode = On) on a public-use production server. This virtually eliminates the need to worry about environment variables being modified and misused:

 ; Safe Mode safe_mode        =    On 

This combination of settings enables you, the administrator, to prohibit environment variables from being modified unless they begin with one of the listed prefixes (safe_mode_protected_env_vars). You can also specify environment variables that, under no circumstances, should ever be allowed to change, regardless of the prefix settings. If there are certain functions you'd rather not be available to users, you can list these here as well (disable_functions).

Finally, to activate the changes, restart Apache again using the Sharing Preferences pane, or by typing sudo /usr/sbin/apachectl restart from the command line.

To verify that PHP is working, create a file (test.php) within one of your web directories (such as Sites within your home directory):

 <?php   phpinfo(); ?> 

Load this test page using a web browser. If the installation was successful, you should see a screen similar to Figure 24.8.

Figure 24.8. The phpinfo() function generates a screen of PHP installation information.


Understanding the PHP Syntax

The best introduction to programming PHP is a background in C or Perl. Check out Chapter 18 as a starter guide for the latter. PHP borrows heavily from Perl's free-form open scripting model and automatic data conversion. What truly makes PHP shine is the built-in web functions. Let's take a brief look at what you need to get started and then examine some of the unique features.

PHP programs are created as standard text files within any of your web-enabled directories. To execute the script, you must have the extension .php. This does not have a bearing on the HTML contents of the file. In fact, you can have an HTML file that contains no PHP code but ends in .php it will still be served correctly, although with a slight performance penalty as the server checks the file for executable code.

PHP code itself is typically embedded within the <?php and ?> brackets. Failing to place these tags around code results in the programming being interpreted as text within an HTML document. Even if you are working with a file that contains no HTML at all, you must still place all the PHP script within the brackets. There can be multiple PHP start and end tags in a single document.

If you've written JavaScript, this is similar to the behavior of the <script> and </script> tags that embed JavaScript code into a document. Regardless of how many PHP code segments are in your program, the code can be considered all part of one big global block. The variables defined in one section are available in another. For example:

 <?php $myname="John"; ?> This is some standard HTML in the middle...<hr><hr> <?php print $myname; ?> 

This code fragment assigns the value John to $myname, includes a bit of HTML, and finally prints the value of $myname (John). Even though $myname occurs within two separate PHP blocks, the value is still maintained.

NOTE

Perhaps not surprisingly, PHP can be embedded with the <script> and </script> tags. To use this format, just include PHP as the scripting language within the first tag: <script language="php">.


Each line of PHP code must end in a semicolon (;) to be correctly executed. Because of this requirement, extremely long lines of code can be broken across multiple lines to improve legibility.

Simple Data Types

Like Perl, PHP's data types are typecast from one to another internally. Although there is one primary data type, PHP is an object-oriented language and is used to create arbitrary object types with their own properties. Object-oriented programming is beyond the scope of this text, so only the basics are covered here. Don't worry; there's more than enough to start building complex web applications.

  • $<variable name> PHP defines a variable as an alphanumeric string prefaced by a $. Variable names cannot begin with a number. The variable can contain text, binary data, numbers, and so on. Type conversion happens automatically during program execution.

  • $<variable name>[<index>] Arrays offer more flexibility than Perl. An array can be defined during the course of program execution by adding an index to the end of a variable name. Unlike Perl, which differentiates between a standard array and associative arrays, an array index in PHP can be either a number or a string.

PHP variables are unique creatures and can be used in interesting ways. For example, the contents of a variable can be interpreted as variables themselves. Assume that you have a variable named $peach. Obviously, you can reference this variable by name ($peach). Now assume that a second variable, $fruit, contains the string "peach". Using this second variable, you can reference the contents of the first variable through $$fruit. This works because $$fruit is functionally identical to typing $"peach", which in turn is equivalent to $peach. This same technique can be applied to function calls to create a logic flow that changes itself based on variables in the program.

NOTE

Although not commonly used in simple applications, PHP does support passing variables by reference. As in C, you can pass a reference to a variable by placing an ampersand (&) in front: &<$variable name>.


Using Basic Variable Operators

The comparison and assignment operations work much like a simplified version of their Perl counterparts. The primary difference is that string comparisons are identical to numeric comparisons in syntax within PHP. Table 24.1 contains the common PHP operators.

Table 24.1. Common PHP Operators

Operator

Action

Description

==

Equals

Tests for equality

!=

Not equal

Tests for inequality

=

Assignment

Assigns the value on the right to the variable on the left

*

Multiplication

Multiplies two values together

/

Division

Divides two values

+

Addition

Adds two numbers together

-

Subtraction

Subtracts one number from another

.

Concatenation

Concatenates two strings together

&&

AND

Performs a logical AND on two values

||

OR

Performs a logical OR on two values


As previously mentioned, PHP automatically handles type conversions for you, making it possible to write code that looks like this:

 <?php $a="1"; $b="3"; $c=$a.$b; $c=$c*2; ?> 

Here, two strings, 1 and 3, are concatenated together and stored in $c. This new value is then multiplied by 2. Printing the result would display 26, even though the only true number used in the calculation was 2 (during the multiplication).

There are a few shortcuts to the assignment as well. For example, incrementing or decrementing a number is common. Written in long form, adding 1 to the existing value of a variable $a looks like this:

 $a=$a+1; 

This can be shortened to

 $a++; 

The same applies to subtraction, using the minus (-) symbol.

Another shortcut applies to concatenating, adding, or subtracting to an existing value. For example, this line of code concatenates $b onto the end of $a:

 $a=$a.$b; 

The same thing can be written as

 $a.=$b; 

For addition and subtraction, just substitute the appropriate operator in place of the period (.). The basic syntax remains the same.

Adding Flow Control

Two types of control structures will be discussed here: linear flow operators and looping constructs. Linear flow operators can change the course of a program based on variables and other conditions. Looping constructs, on the other hand, can repeat sections of code based on similar criteria. Together they enable software to adapt to a particular task, instead of being hard-coded to work with one set of input.

if-then-else The most common linear flow control structure is the if-then-else statement. This can evaluate one or more conditions and act on them accordingly. The basic PHP if-then statement is structured like this:

 if <condition> {     <do something>; } 

This statement can be expanded to include an alternative course of action if the original condition is not met. This is considered an if-then-else statement:

 if <condition> {     <do something>; } else {     <do something else>; } 

One final variation of the statement exists that can evaluate multiple conditions within the single statement. This last variation is the if-then-elsif statement.

 if <condition> {     <do something>; } elsif <another condition> {     <do something else>; } else {     <do yet another thing>; } 

This example includes a single elsif line, but, depending on the needs of the programmer, this can be repeated as many times as necessary. A less verbose way to accomplish the same goal is to use the switch statement.

switch The switch statement takes a value as input and defines a set of possible outcomes that can occur, depending on that value. The best way to understand how this works is to look at an example:

 switch ($x) {     case 0:         print "x=0";         break;     case 1:         print "x=1";         break;     case 2:         print "x=2";         break;     default:         print "none of the above";         break; } 

This piece of code examines the value of $x. If it is 0, PHP prints x=0. If $x equals 1, the code prints x=1,..., and so on. If $x doesn't match any of the listed values (0, 1, 2), it uses the default value and prints none of the values listed earlier.

The switch statement can be extended to include as many cases as needed. In addition, the cases do not have to be numeric. You can just as easily include strings:

 switch ($name) {     case 'John':         print "John has a dog named Maddy";         break;     case 'Robyn':         print "Robyn has a dog named Coco";         break;     case 'Jack':         print "Jack has a bag of M&Ms";         break;     case default:         print "I don't know you!";         break; } 

The two portions of the switch statement that might require a bit more explanation are the break statement and the default case.

The break causes the switch statement to exit. If break is not executed, all code after the matching case is executed. If John is matched, all the print statements are executed until a break is encountered.

The default case is optional. It is executed only if none of the other cases is matched. It's usually a good idea to have a default case to keep untrapped errors from occurring.

for The for loop is the most commonly encountered loop in programming, regardless of the language. This loop executes a block of code until a condition is met. Each iteration of a for-next loop increments (or decrements) a counter variable. The loop is constructed using this syntax:

 for (<initialization>;<execution condition>;<increment>) {     <code block> } 

The initialization sets up the loop and initializes the counter variable to its default state. The execution condition is checked in each iteration of the loop; if it evaluates to false, the loop ends. Finally, the increment is a piece of code that defines an operation performed on the counter variable each time the loop is run. For example, the following loop counts from 0 to 9:

 for ($count=0;$count<10;$count++) {     print "Count = $count"; } 

The counter, $count, is set to 0 when the loop starts. With each repetition, it is incremented by 1 ($count++). The loop exits when the counter reaches 10 ($count<10).

The format for the PHP for loop is identical to the Perl syntax.

while The while loop executes while a condition evaluates to true. Unlike a for loop, which usually ends based on a change in the counter, the while loop requires that something change within the code block that causes the condition to evaluate as false.

 while (<execution condition>) {     <code block> } 

The previous for example counted from 0 to 9. This same loop translated into a while loop looks like this:

 $count=0; while ($count<10) {     print "Count = $count";     $count++; } 

When you're using while/do-while loops, be sure that the execution condition eventually evaluates to false. It's easy to write infinite loops using this structure.

do-while Similar to the basic while loop, a do-while loop runs until a preset condition evaluates to false. The difference between the two loop styles is where the execution condition is checked. In a while loop, the condition is evaluated at the start of the loop. do-while loops, on the other hand, evaluate the condition at the end:

 do {     <code block> } while (<execution condition>); 

Again, let's translate the count from 0 to 9 into a do-while loop. As you can see, the difference is slight.

 $count=0; do {     print "Count = $count";     $count++; } while ($count<10); 

NOTE

Many languages have a similar loop structure known as a do-until loop. The only difference is that the do-until loop exits after a condition is met, not after it has become false.


Implementing Functions

Like any good programming language, PHP supports the notion of functions independent pieces of code that can act on input and return a result. As you develop web applications, you'll find that a reasonable amount of code is reused each time. If applications are programmed as modularly as possible, you can create a library of commonly used functions to share among multiple applications and developers.

A function is set up using the function keyword; values are returned to the main program using return. For example:

 function addnumbers($arg1,$arg2) {     $result=$arg1+$arg2;     return($result); } 

This function accepts two arguments ($arg1 and $arg2), adds them together, and then returns the result to the main program. The addnumbers function could be called like this:

 $theresult=&addnumbers(1,5); 

In this example, the function is called with a preceding ampersand (&). This is optional but is required in code where the function's definition occurs after the function call is used in the code.

By default, all variables used in a function are automatically considered local to that function and cannot be accessed outside the function code. To make a variable's scope global, use the global keyword within a function:

 global <variable name>; 

A variable that is declared global can be accessed from the main program block as well as the declaring function.

Common Useful Functions

It's pointless to try to document all PHP's capabilities in this chapter. More than 1,500 functions are available in the PHP 4.3.x release. Table 24.2 provides a quick reference to some of the more interesting and useful functions. For those who are interested, when compiling this list I surveyed more than a dozen PHP scripts and noted the most frequently used operations as well as those needed for the examples in the chapter.

Table 24.2. With More Than 1,500 Available Functions, PHP Is Anything But Limited

Function

Purpose

addslashes(<string>)

Escapes special characters within strings (such as '"') and returns the resulting string.

chop(<string>)

Removes trailing whitespace from a string and returns the result.

file(<url>)

Reads a file from a URL (local, FTP, web) and returns an array of each line in the file.

header(<string>)

Outputs a header before processing any HTML output.

join(<glue string>,<array>)

Returns a single string containing all the elements of a given array joined together with the glue string. Same as implode.

odbc_connect(<DSN>,<user>,<password>)

Returns a link to an ODBC DSN on a given host.

odbc_close(<link>)

Given a database link, closes the connection.

odbc_exec(<link>, <sql statement>)

Sends an SQL statement to the ODBC DSN. Returns a pointer to the resulting data.

odbc_fetch_array(<result>)

Returns an array with the next available row of data from the resultset. The array is indexed by field name.

odbc_num_rows(<result>)

Returns the number of rows in a query result, or an error if the original query was invalid.

preg_replace(<regex>,<replace string>,<string>)

Searches a string for a Perl-style regular expression, replaces it with another, and returns the new string.

print "<output>"

Displays an output string. This is identical to the echo keyword.

opendir(<directory name>)

Opens a directory for reading and returns a file handle.

readdir(<file handle>)

Returns the next filename within a directory opened with opendir. Returns false if no more files are available.

require(<filename>)

Includes the contents of another file within the PHP code.

session_start()

Initializes a new session.

session_destroy()

Removes the active session.

sort(<array>)

Sorts an array.

soundex(<string>)

Returns a soundex value for a given string. This value is based on the sound of a string and can be used to compare two strings that sound similar but are spelled differently.

split(<pattern>,<string>)

Splits a string based on the characters in <pattern> and returns each of the results as the element in an array.

stripslashes(<string>)

Removes slashes from a string the opposite of addslashes and returns the result.

strlen(<string>)

Returns the length of a given string.


Visit http://www.php.net/quickref.php for a full list of the PHP functions.

PHP in Practice

In the Perl portion of this chapter, we created a simple image catalog. Let's see how that catalog can be rewritten in PHP. Listing 24.9 shows a PHP version of the Perl-image catalog.

Listing 24.9. The Image Catalog, Rewritten in PHP
 1: <?php if (!$_POST['imagedir']) { ?> 2:     <form action="showimages1.php" method="post"> 3: Choose image dir: <input type="text" name="imagedir" value="imagefolder"><br> 4:     Select the number of columns in the display: <select name="columns"> 5:       <option>1</option> 6:       <option>2</option> 7:       <option>3</option> 8:       <option>4</option> 9:     </select><br> 10:    Show images that match: <input type="text" name="match"> 11:    <input type="submit" name="submit"> 12:    </form> 13: <?php exit; } ?> 14: 15: <table bgcolor="#FFFFFF" border="1" bordercolor="#000000"> 16: <?php 17: $imagedir=$_POST['imagedir']; $columns=$_POST['columns']; 18: $handle=opendir("$imagedir"); 19: while ($imagename = readdir($handle)) { 20:   if ($count==0 && $loop==0) { print "<tr>"; $loop=1; } 21:   if (preg_match("/.*$match.*\.jpg$/i",$imagename)) { ?> 22:    <td align=center> 23:    <img src="/books/4/382/1/html/2/<?php print"$imagedir/$imagename"; ?>"                    width="120" height="90"><br> 24:    <font type="Arial"><?php print $imagename; ?></font> 25:    </td><?php 26:    $count++; 27:    if ($count==$columns) { print "</tr>"; $count=0; $loop=0; } 28:   } 29: } 30: if ($count!=0) { print "</tr>"; } 31: ?> 32: </table> 

The first two things you should notice looking at this code are that it is shorter than the Perl code and that the PHP is embedded in the HTML, rather than the HTML being embedded in the programming.

As the PHP application begins sending output, it automatically adds a text/html Content-Type header. In addition, no additional library or module, such as CGI.pm, is required. When a form posts information to a PHP program, the form variables are automatically translated into PHP variables with the $_POST[] or $_GET[] superglobal associative arrays. For example, an input field with the name address becomes accessible as $_POST['address'] when submitted to a PHP script. A more generalized superglobal array $_REQUEST[] can be used to reference any variable that is available either from a POST, GET, or cookie. These shortcuts enable you to focus on the code rather than the specifics of HTTP.

A breakdown of the changes in the code follows:

Lines 1 13 check whether the variable imagedir has been posted from a form. If it hasn't, the user hasn't submitted a search request yet, and the search form should be displayed. Unlike Perl, which used print to show the form, PHP if-then tags can encompass HTML blocks. In this case, if the variable isn't defined, the HTML in the if-then is sent to the browser; otherwise, it is skipped.

Line 15 starts the HTML output table. In Line 17, the variables $imagedir and $columns are assigned to the values posted from the web form. Line 18 opens the image directory for reading. PHP, sadly, doesn't support a glob function, like Perl. While there are files in the opened directory, lines 19 29 parses them into $imagename.

If at the start of a row, send a <tr> tag. Line 20 must also set a flag ($loop) to indicate that the loop has started; this prevents multiple <tr> from being sent if the first few files read in the directory are not image files. Line 21 uses a Perl regular expression to match the filename to a file that ends in .jpg and includes the search string ($match).

Lines 22 25 display the table data cell for the image. Note that the image name is added to the HTML by embedded PHP print statements. Lines 26 27 increment the number of images displayed. If it is equal to the selected number of image columns, output a </tr>.

If the last file displayed occurred in the middle of a row, the program must add a final </tr> to close the row. This is done with line 30. Line 32 closes the output table.

For the most part, the programming syntax should closely resemble what you've seen in Perl. The lack of a glob function adds a few extra lines but doesn't prevent the PHP version from coming in 20% shorter.

Using Sessions in PHP

I've made such a big deal about sessions and how they make life easier; it's probably time to see one in use. Unfortunately, it's difficult to fabricate the use for a session in a reasonable amount of space. So, let's take a look at a simple case of sessions at work.

Imagine having a web page that remembers how many times you've visited it during your current browser session (since you last quit out of your web browser). This can't be done using a form because an action would be needed to submit the form each time you load the page. URL parameters can't be used because, likewise, the page would have to alter all the links it contains to include the number of visits using URL variable passing. With sessions, this is beyond simple. In fact, the following example keeps track of the cumulative number of visits to two distinct pages.

Create two web pages (one.php and two.php) that link to one another. In one.php, type the following:

 <?php         session_start();         $_SESSION['x']++;         $x=$_SESSION['x'];         print "You've been to page one and two $x times"; ?> <br/> <A HREF="two.php">Go to page two</a> 

And in two.php, type this:

 <?php         session_start();         $_SESSION['x']++;         $x=$_SESSION['x'];         print "You've been to page one and two $x times"; ?> <br/> <a href="one.php">Go to page one</a> 

Open either of the pages in your browser. Clicking the link to toggle between the two pages increments the counter, and the displayed number starts counting up. Although this is not a groundbreaking website, it demonstrates the capabilities of built-in session management. The two pages share a single counter session variable: x. The session_start() command starts a new PHP session if one doesn't already exist. The $_SESSION['x']++ registers the variable x with the current session and adds one to its current value. Changing anything in the $_SESSION[] array effectively saves its value between pages. The $x=$_SESSION['x'] statement simply brings the session variable x into a normal local variable $x that is easier to work with.

The incrementing of x doesn't depend in any way on the links between one.php and two.php. You can reload one of the pages 30 times, and the counter will increment 30 times. You can even visit another website and then come back to either of the web pages, and the count is still present. The only way to lose the value of x is to drop the session that is, close your web browser.

Accessing ODBC Data Sources in PHP

Finally, as an example of PHP's capability to work with databases, let's take a look at how easily code can be written to interact with an ODBC DSN (covered in detail in Chapter 19, "Serving and Connecting to Databases"). Because most database-driven websites require a bit of setup, this example assumes that your Tiger installation is set up with a DSN called myDSN with a username databaseuser and password databasepass.

The database itself is named employee and contains a table tblemployee with at least the two fields firstname and lastname. You should easily be able to adapt this short script to work with any ODBC database you can design, or just use the sample database in Chapter 19. Listing 24.10 demonstrates PHP that retrieves and prints each person's name from employee.

Listing 24.10. PHP/ODBC Example
 1: <?php 2: $odbclink=odbc_connect("myDSN","databaseuser","databasepass"); 3: $result=odbc_exec($odbclink,"select * from tblemployee"); 4: $count=odbc_num_rows($result); 5: for ($x=0;$x<$count;$x++) { 6:    $record=odbc_fetch_array($result); 7:    $firstname=$record[FirstName]; 8:    $lastname=$record[LastName]; 9:    print "$lastname, $firstname<br/>"; 10: } 11: odbc_close($odbclink); 12: ?> 

Line 2 makes the initial connection to the ODBC DSN with the username/password pair databaseuser/databasepass. The variable $odbclink can be used to refer to the connection.

Line 3 queries the ODBC database employee by sending it the SQL query select * from tblemployee. A pointer to the resultset is returned to the variable $result.

Line 4 stores the total number of records in the result in the variable $count.

Lines 5 10 loop through the number of available records. Line 6 stores each row (one per loop) in the array $record. Lines 7 and 8 retrieve the firstname and lastname fields from the record, storing them in the $firstname and $lastname variables, respectively. Line 9, finally, outputs the name.

Line 11 closes the connection created in Line 2.

TIP

This example demonstrates how to pull information from a DSN, but the process for storing data is identical. The odbc_exec function can be used to send any SQL statement to the database server and retrieve the results. You could just as easily use an insert or update SQL command in place of the select shown here.


The virtues of PHP could be touted for pages, but, unfortunately, the room is not available. If you want more information on PHP development, look at any of these fine sites:

  • PHP Homepage http://www.php.net/

  • PHP Builder http://www.phpbuilder.net/

  • comp.lang.php PHP's official Usenet newsgroup

Additionally, Zend Technologies (http://www.zend.org) has released its Zend IDE for Mac OS X, which makes creating and debugging PHP applications much like working with traditional desktop applications.

     < Day Day Up > 


    Mac OS X Tiger Unleashed
    Mac OS X Tiger Unleashed
    ISBN: 0672327465
    EAN: 2147483647
    Year: 2005
    Pages: 251

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net