Like the other languages we've studied (and most easy-to-use languages), PHP is whitespace-insensitive. Therefore, this statement: <? $title="PHP is cool";echo "<title> $title </title>"; ?> might be clearer if written as this: <? $title = "PHP is cool"; echo "<title> $title </title>"; ?> Variable names in PHP are case-sensitive ” $a is different from $A . Function names (including user -defined functions) are case-insensitive ” rose() is equivalent to ROSE() is equivalent to Rose() . As in C, C++, Java, and Perl, statements are terminated by a semicolon. Also as in C, C++, and Java (but not Perl), single-line bodies do not require the curly braces ( {} ), while multiline bodies do: <? // one-line bodies do not require the curlies, // but using them would be ok if ($num > 10) echo "$num is greater than 10"; // in this example, the curlies are required if ($name == "John Doe") { echo "You say your name is John Doe"; echo "Are you sure that is your name?"; } ?> PHP supports three types of comments: # Perl/sh style - comment until end of line /* C style */ // C++ style (preferred for one-line comments) C-style comments can span more than one line: /* the following code is so cool, it almost doesn't need to be commented */ 12.5.1 VariablesAll variable names (including arrays) begin with a dollar sign ( $ ) followed by an alpha (A “Z, a “z) or underscore (_), followed by zero or more alphanumeric characters or underscores (there is no limit on variable name length): $i $_1st_name $array[0] As in other scripting languages, such as Perl and shell scripts, variables do not need to be declared. 12.5.2 Data TypesPrimitive Data TypesPHP has three primitive data types: integers, floats, and strings.
Data Type ExamplesThis example shows how PHP uses the various data types. This code can be found in the file /var/www/html/php/variables.php : <? // assign some variables the different data types $integer = 12; $float1 = 1.345e23; $float2 = 4995.392; $string1 = My favorite number is $integer; $string2 = "I am this big: $float1 or $float2"; ?> <html> <head> <title>Integers, Floats and Strings in PHP</title> </head> <body bgcolor="#ffffff"> Integer: <b><? echo $integer; ?></b><br> Float 1: <b><? echo $float1; ?></b> <i>note that the format is *almost* the same as assigned</i><br> Float 2: <b><? echo $float2; ?></b> <i>the format is the same as assigned</i><br> String 1: <b><? echo $string1; ?></b><br> String 2: <b><? echo $string2; ?></b> </body> </html> An integer, two floats, and two strings are demonstrated. The two floats are assigned in a different format, and PHP maintains that format (well, almost ”our lowercase "e" is replaced with an uppercase "E"). The difference between single quotes and double quotes is demonstrated. To view the result of this program, load in either http://localhost/php/variables.php or www.opensourcewebbook.com/php/variables.php. This produces Figure 12.3. Figure 12.3. PHP data types
ArraysTo index a PHP array, use the syntax $array[n] , where [n] is an integer beginning at 0, as in Perl. But when referring to the entire array, use the dollar sign ( $ ) ” sort ($array) ”not the at sign ( @array ) of Perl. PHP arrays can be treated in one of two ways: as enumerated arrays or as associative arrays. Enumerated Arrays Enumerated arrays are zero-based arrays indexed with integer values ” $array[0] : <? $a[0] = 10; $a[1] = 4*4; $a[2] = 12; echo $a[0] + $a[1] + $a[2]; // echoes 38 ?> Enumerated arrays can be created as shown by simply assigning values to each array index, or they can be created with the array() function, which returns an array of values: <? $a = array(2, 4, 6, 8); echo $a[0]; // echoes 2 $b = array("foo", "bar", "blah"); echo $b[1]; // echos bar ?> Associative Arrays Associative arrays are indexed with unique strings ” $array["key"] ”like Perl hash variables: <? $capital["Illinois"] = "Springfield"; $capital["California"] = "Sacramento"; $capital["Texas"] = "Austin"; $capital["Wisconsin"] = "Madison"; $state = "Illinois"; echo "$state: $capital[$state]"; // echoes "Illinois: Springfield" ?> Associative arrays can be created by assigning values individually to keys as just shown, or they can be created with the array() function: <? $capital = array("Illinois" => "Springfield", "California" => "Sacramento", "Texas" => "Austin", "Wisconsin" => "Madison"); $state = "Illinois"; echo "$state: $capital[$state]"; // echoes "Illinois: Springfield" ?> The array() function is useful. PHP has many more built-in functions to process arrays. We examine some of these later in the chapter. 12.5.3 Web VariablesPHP can be used to process data that is submitted via forms; such data is accessible in several ways. To illustrate this, create a simple form in /var/www/html/php/form1.html : <html> <head> <title>PHP Form Example 1</title> </head> <body bgcolor="#ffffff"> <form action="/php/form1.php"> Var 1: <input type="text" name="var1"> <br> Var 2: <input type="text" name="var2"> <br> <input type="submit"> </form> </body> </html> The result of using this form, with example data entered into the widgets, is shown in Figure 12.4. When the form is submitted, the form data is passed to the PHP program in several ways. Figure 12.4. PHP form 1
When the data is posted to the PHP program specified in the action= form attribute ( /php/form1.php in this example), PHP variables are automatically created in that PHP script when it executes. These variables have the same name as the form elements, preceded by " $ ". In this form, there are two fields ” var1 and var2 ”so PHP creates two variables in /php/form1.php : $var1 and $var2 . An Important Security ConsiderationThis "feature" of PHP can create a huge security hole. Consider this code: if (something_important()) { $authenticated = true; } Here we are relying on something_important() to verify that we can set the authentication flag to true. We can assume something_important() does, er, something important to authenticate the user. However, it would be easy to pass a parameter to this program using the name/value pair that we want, as in: http://localhost/php/big_security_hole.php?authenticated=true Doing this would magically set $authenticated to true. Therefore, even if something_important() returned false, the very important flag $authenticated would be assigned true ”very bad. Therefore, we strongly suggest that you turn off this feature for PHP. You can do so for the entire site or for a specific directory. Because this is a nasty problem, we suggest that you turn it off for the whole site by adding this line to /etc/httpd/conf/httpd.conf : php_flag register_globals Off To turn it off for only a specific directory in the web document tree, add this to the configuration file: <Directory /var/www/html/php> php_flag register_globals Off </Directory> Load the new config file: # /etc/init.d/httpd graceful Now that PHP is more secure, let's talk about how to grab the posted data. PHP Version 4.1.0 has added a new and strongly suggested approach to grabbing the posted data. However, as of this writing, version 4.1.0 had just been released, and Red Hat had not yet released a binary for it. Therefore, we first discuss how to use the pre-4.1.0 approach and then discuss the 4.1.0 way. [5]
Pre “PHP Version 4.1.0PHP has two special array variables that are magically assigned the data passed into the program: $HTTP_GET_VARS and $HTTP_POST_VARS . All the data passed in using the GET method is stored in the array $HTTP_GET_VARS , so the value of the field var1 can be accessed with $HTTP_GET_VARS["var1"] . If the data were passed to the program using POST instead of GET , the data would be passed into the array $HTTP_POST_VARS instead, so the data could be accessed with $HTTP_POST_VARS["var1"] . It is useful have both variables because we can post data through the form and at the same time use the GET method to pass the data through the URL. The parameters can have the same names (not always a good idea, but it can be done) and grab the posted data from $HTTP_POST_VARS and the URL data from $HTTP_GET_VARS . The file that processes the form data from the previous form, /php/form1.php , looks like this: <html> <head> <title>PHP Form 1 Result</title> </head> <body bgcolor="#ffffff"> Using $var1: <b> <? echo $var1; ?> </b> <br> Using $var2: <b> <? echo $var2; ?> </b> <br> Using $HTTP_GET_VARS: <b> <? echo $HTTP_GET_VARS["var1"]; ?> </b>, <b> <? echo $HTTP_GET_VARS["var2"]; ?> </b> </body> </html> This program produces Figure 12.5. Figure 12.5. PHP form 1 result
The good news is that $var1 and $var2 are not magically assigned (because we turned off register_globals ”you can see that there is nothing echoed out by <? echo $var1; ?> ). This is a good thing. Post “Version 4.1.0Version 4.1.0 adds a new, improved, and strongly suggested approach to grabbing the posted data. Because Red Hat version 7 does not include PHP version 4.1.0, we will only discuss it here ”the remaining examples use the pre-4.1.0 method. In the future, you should use the new way. PHP version 4.1.0 has added several new global variables:
Version 4.1.0 introduces some other helpful variables:
Therefore, the preceding example could change to this: Using $_GET: <b> <? echo $_GET["var1"]; ?> </b>, <b> <? echo $_GET["var2"]; ?> </b> or this: Using $_REQUEST: <b> <? echo $_REQUEST["var1"]; ?> </b>, <b> <? echo $_REQUEST["var2"]; ?> </b> 12.5.4 OperatorsPHP operators are similar to the ones available in Perl, including precedence (see www.php.net/manual/en/language.operators.precedence.php). One exception is that there are no string comparison operators. The comparison operators ( == , < , etc.) are used to compare both numbers and strings, as in $name == "Joe" . The or and and OperatorsLike Perl, PHP has the or and and operators, often used with short-circuited evaluation: $name == "Joe" or print "Name is not Joe"; You can also write this logic with the and , but this is less common: $name != "Joe" and print "Name is not Joe"; 12.5.5 Flow-Control ConstructsPHP's constructs are similar to those of C and Perl. However, for most of the constructs, PHP has two preferred syntax forms. The first is C-like and is suggested when the entire block is contained within a single PHP block. The second is useful when the PHP code is embedded within a large block of HTML. As in C, C++, and Java (but not Perl), the curly braces are optional for the bodies of the constructs if the body is one statement. if/elseif/else Here are the two PHP syntaxes for an if : if ( condition ){ statements }elseif ( condition ){ statements }else{ statements } and: if ( condition ): statements elseif ( condition ): statements else : statements endif; As an example (this can be found in the file named /var/www/html/php/if.php ): <? $name = $HTTP_GET_VARS["name"]; $age = $HTTP_GET_VARS["age"]; // this syntax is recommended when the entire if // is contained within a PHP block like this one $msg = "You $name are "; if ($age < 13) { $msg = $msg . "a child"; } elseif ($age < 18) { $msg = $msg . "a teenager"; } elseif ($age < 62) { $msg = $msg . "an adult"; } else { $msg = $msg . "a senior"; } // the syntax of the if statement below is // recommended if you have embedded PHP code ?> <html> <head> <title>PHP if statement</title> </head> <body bgcolor="#ffffff"> <? echo $msg; ?> <hr> <? if ($name < "N") : ?> Your name begins with A through M <? else: ?> Your name begins with N through Z <? endif; ?> </body> </html> The result of this code can be examined by invoking the program and passing data into it through either of these URLs so that it is treated as GET data: http://localhost/php/if.php?age=39&name=John+Doe or www.opensourcewebbook.com/php/if.php?age=39&name=John+Doe. The result can be seen in Figure 12.6. Figure 12.6. PHP if example
switchLike C and C++, PHP has a switch statement. Like the PHP if , it has two different syntaxes: switch ( expression ){ case expr : statements break; case expr : statements break; default: statements break; } and: <? switch ( expression ): case expr : statements break; case expr : statements break; default: statements break; endswitch; ?> As in C and C++, the break in each branch is crucial. If it weren't there, program execution would just flow through each executable statement in the switch construct following the valid one, not just the ones related to the specific case. The switch is often used to replace the nested if where each conditional expression compares the same variable against a value. An if statement: <? if ($i == 0) { statements0 } elseif ($i == 1) { statements1 } elseif ($i == 2) { statements2 } elseif ($i == 3) { statements3 } elseif ($i == 4) { statements4 } ?> can be rewritten as a switch: <? switch ($i) { case 0: statements0 break; case 1: statements1 break; case 2: statements2 break; case 3: statements3 break; case 4: statements4 break; } ?> while LoopPHP's while loop is C-like, and as one might expect, also has two syntaxes: while ( condition ){ statements } and the second one: while ( condition ): statements endwhile; Like C, C++, and Java, PHP allows one to break out of a loop with break and go to the next iteration with the continue statement. do ... while LoopPHP also has a do ... while loop: do { statements }while ( condition ); for LoopPHP has a C-like for loop with two syntax options: for ( start_expr ; condition ; step_expr ){ statements } and: for ( start_expr ; condition ; step_expr ): statements endfor; foreach LoopPHP has a Perl-like foreach loop, which iterates through arrays in two distinct ways. Each foreach method has two syntax variations. The first method returns only the value and is used to iterate through enumerated arrays. The syntax is: foreach ( array_expr as variable ){ statements } or: foreach ( array_expr as variable ): statements endforeach; These constructs loop through the array represented by array_expr , assigning the variable variable the value of that element. The following is an example: <? $array = array(2, 4, 6, 8); foreach ($array as $value) { echo "$value "; } // echoes "2468" ?> Here, $value takes on each value of the array $array , and the body is executed for each of those values. The variable $value is first 2 , then 4 , then 6 , and finally 8 . The second foreach method returns both the key and the value, which is used to iterate through associative arrays. It has this syntax: foreach ( array_expr as key => value ){ statements } or: foreach ( array_expr as key => value ): statements endforeach; Unlike in Perl, key/value arrays are not stored in an apparent random order (based on how the keys hash). They are stored in the order created. This version of foreach loops through array_expr , assigning the next key/value pair to key , value . Here is an example: <? $array = array("name" => "John Doe", "age" => 39, "phone" => "555-1234"); foreach ($array as $k => $v) { echo "$k: \t $v \n"; } // echoes: // name: John Doe // age: 39 // phone: 555-1234 ?> Note that the foreach that iterates through an associative array can be used to iterate through enumerated arrays. The indices , 1 , and so on are treated as the keys: <? $a = array(2, 4, 6, 8); foreach ($a as $k => $v) { echo "$k = $v"; } // echoes: 0 = 2 // 1 = 4 // 2 = 6 // 3 = 8 ?> The following example shows the various looping constructs and can be found in /var/www/html/php/loops.php . It shows how to loop through an enumerated array using while , for , and foreach . It then demonstrates iteration through an associative array with a foreach . <? // enumerated array of numbers $nums = array(2, 4, 6, 8); // associative array of names and ages $ages = array("Ron" => 31, "Gail" => 26, "Al" => 38, "Tom" => 36); ?> <html> <head> <title>Examples of PHP Loops</title> </head> <body bgcolor="#ffffff"> <h3>Loop through $nums with the while loop</h3> <? $i=0; while ($i < 4) { echo "$nums[$i] "; $i++; } ?> <h3>Loop through $nums with the for loop</h3> <? for ($i = 0; $i < 4; $i++) { echo "$nums[$i] "; } ?> <h3>Loop through $nums with the foreach loop</h3> <? foreach ($nums as $v) { echo "$v "; } ?> <h3>Display ages in a table using the foreach loop</h3> <table border="1"> <? foreach ($ages as $k => $v) { echo "<tr><th>$k</th><td>$v</td></tr>"; } ?> </table> </body> </html> To give this code a test drive, put one of the following URLs into your browser: http://localhost/php/loops.php or www.opensourcewebbook.com/php/loops.php. The proof is in the pudding, in Figure 12.7. Figure 12.7. PHP loops example
12.5.6 Writing PHP FunctionsThe syntax to declare a function is: function function_name ( variable_list ) { statements } The syntax to call a function is: function_name ( variable_list ); Look in /var/www/html/php/function1.php for the familiar hello, world! example: <? function print_hello () { echo "hello, world!"; } ?> <html> <head> <title>PHP Functions - Part 1</title> </head> <body bgcolor="#ffffff"> <? print_hello(); ?> </body> </html> This program defines the function print_hello() , which, as you might guess, prints "hello, world!". The function is defined within the <? ... ?> tags, just like any other PHP code. It is then invoked within the <body> tags with <? print_hello(); ?> . The result can be seen by loading one of these URLs: http://localhost/php/function1.php or www.opensourcewebbook.com/php/function1.php. The result will be the familiar, hypnotic, spiritual "hello, world!" displayed in the browser. PHP functions can return values (covered next) and take arguments (covered later). Return ValuesAPHP function can return a single value or an array of values. The return statement returns the value from the function to the caller. This example illustrates the return of a string, an array of integers, and an associative array. This code can be found in /var/www/html/php/function3.php : <? function return_string() { // return a string return "hello, world!"; } function return_array1() { // return an array of integers return array(2, 4, 6, 8); } function return_array2() { // return a more complicated array $a = array("one" => "first", "two" => "second", "three" => "third"); return $a; } ?> <html> <head> <title>PHP Functions</title> </head> <body bgcolor="#ffffff"> <? // echo the return value from return_string() echo return_string(); ?> <hr> <? // grab the array returned from return_array1() // foreach through it, echoing the value $array1 = return_array1(); foreach ($array1 as $value) { echo "$value <br>"; } ?> <hr> <? // grab the array returned from return_array2() // foreach through it, echoing the keys and values $array2 = return_array2(); foreach ($array2 as $k => $v) { echo "$k : $v <br>"; } ?> </body> </html> Notice the variable $a within the function return_array2() ? It is by definition locally scoped. All variables within a function are by default locally scoped to the function in which they are used. [6]
To try this program, load in either http://localhost/php/function2.php or www.opensourcewebbook.com/php/function2.php. You should see something like Figure 12.8. Figure 12.8. PHP function2 example ”return values
Function ArgumentsAs in all other languages, arguments can be passed to PHP functions, as follows : function no_default_args($a, $b, $c) { echo "<hr>"; echo "no_default_args(): $a : $a <br>"; echo "no_default_args(): $b : $b <br>"; echo "no_default_args(): $c : $c <br>"; } This function is called no_default_args solely because it does not have default argument values. It accepts three arguments: $a , $b , and $c . It then prints an <hr> tag, followed by the value of the three variables. As with all variables within a function, the three variables in this function are by default locally scoped. To call this function, simply put the arguments within the parentheses: no_default_args("foo", $variable_name, 4.9485); If this function were called with fewer than three arguments, a warning message would be displayed, and the function would execute with the variables that were not passed a value being given the value of the empty string. If this function were called with more than three arguments, the extra arguments would be ignored. This invites the question, "Can a function be written so that the arguments are given default values if values are not provided?" The answer is, of course, yes. [7] In this sort of application, in which unknown users will be passing information into your system, all values should have default, sane values.
To provide default arguments to a function, simply assign the variable within the parentheses in the function definition: function default_args($a = 2, $b = 4, $c = 6) { echo "<hr>"; echo "default_args(): $a : $a <br>"; echo "default_args(): $b : $b <br>"; echo "default_args(): $c : $c <br>"; } In this function, $a accepts the value of the argument passed to it, or it defaults to 2 if no value is given. If the function is called as: default_args("foo", "bar", 10.498); $a receives the value "foo" , $b receives value "bar" , and $c receives the value 10.498 . If the function is called as: default_args("foo"); $a receives the value "foo" , but $b receives its default value, 4 , and $c receives its default value, 6 . If the function is called as: default_args(); each variable receives its default value. Arguments can be dropped only at the end of the list, not at the beginning. [8] Thus default_args(,"bar"); is a syntax error. You must provide the value for the first argument:
default_args(2, "bar"); Let's look at a complete example. It illustrates the two preceding concepts plus it shows that a function can receive as its argument an array variable. The example can be found in /var/www/html/php/function3.php : <? function no_default_args($a, $b, $c) { echo "<hr>"; echo "no_default_args(): $a : $a <br>"; echo "no_default_args(): $b : $b <br>"; echo "no_default_args(): $c : $c <br>"; } // this function is defined so that the arguments // have default values function default_args($a = 2, $b = 4, $c = 6) { echo "<hr>"; echo "default_args(): $a : $a <br>"; echo "default_args(): $b : $b <br>"; echo "default_args(): $c : $c <br>"; } // this function accepts an array function expects_array($a) { echo "<hr>"; foreach ($a as $k => $v) { echo "expects_array(): $k : $v <br>"; } } ?> <html> <head> <title>PHP Functions - Arguments</title> </head> <body bgcolor="#ffffff"> <? // no_default_args() expects 3 arguments no_default_args("foo", "bar", 20); no_default_args(10, 48*23, 1.884e-23); // this one only passes in 2 args, but the function // expects3-awarning message is generated and // the last arg gets empty string no_default_args(1,2); // use the defaults default_args(); // override the first two defaults, use the third default default_args("foo","bar"); // create an array to pass into expects_array() $array = array("one" => "first", "two" => "second", "three" => "third"); // pass in an array because that is what it expects expects_array($array); // pass in a string, yet it expects an array - warning message! expects_array("foo"); ?> </body> </html> As the comment implies, calling no_default_args() without three arguments generates a warning message. Calling expects_array() , a function that expects its argument to be an array, with an argument that is not an array produces a warning message. To try this program, load in either http://localhost/php/function3.php or www.opensourcewebbook.com/php/function3.php. The resulting error messages can be seen in Figure 12.9. Figure 12.9. PHP function3 example ”function arguments
|