InformIT

PHP Basics: Writing Simple PHP Applications

Date: Nov 22, 2002

Sample Chapter is provided courtesy of Sams.

Return to the article

Ewald Geschwinde and Hans-Juergen Schoenig discuss how to write simple PHP applications. Learn the basics of PHP syntax as well as PHP's built-in functions.

PHP is an easy language and you'll find it an easy task to get used to PHP. In this chapter you learn to write simple PHP applications. You learn the basics of PHP syntax as well as PHP's built-in functions.

3.1 Getting Started

In this section you learn to write simple applications. The basics of PHP's interpreter are also covered in detail.

3.1.1 "Hello World"

The first application you will find in most books about computer programming is "Hello World". "Hello World" is easy to implement in all languages because it does nothing except print a string on the screen, so it is a good start. Here is the easiest version of "Hello World" written in PHP:

<?php
    echo 'hello world<br>';
?>

With just three lines of code, you can print a simple message on the screen. The first line of code tells the Web server that the next lines of code have to be executed by the PHP interpreter. ?> means that the code ends here. Using <?php is not the only possible way to tell the Web server that PHP code has to be executed. PHP provides three additional ways to escape from HTML:

<?
    echo 'hello world 1<br>';
?>
 
<script language="php">
    echo 'hello world 2<br>';
</script>
 
<%
    echo 'hello world 3<br>';
%>

In the first three lines, you can see that it is not necessary to mention that the PHP interpreter has to be called. This method of escaping HTML is possible only when short tags are enabled (you can do this by setting the short_open_tag option in PHP's configuration file). However, to make clear which programming language is meant, we recommend using <?php instead of <?.

The third method can be used if Active Server Pages (ASP) tags are enabled. If ASP tags are turned off, <% and %> will be treated like ordinary text and the PHP code will not be interpreted. Therefore we recommend using either <?php or <script language="php"> to tell the Web server what to do with the PHP code. In this book we will use <?php to escape HTML.

If you have put the file containing the code into the right directory (see the documentation and configuration of your Web server to find the right directory), you can execute the script by accessing it in your Web browser. If the file is called hello.php and if it is in the default HTML directory of your local machine, it can easily be accessed by using http://localhost/hello.php. You do not have to add execute rights to the file because the Web server only has to read the file.

If everything has been done correctly, PHP has been configured successfully, and your Web server has been started, hello world will be displayed on the screen.

Your first version of "Hello World" produces just text. However, the main target of a PHP program is to generate HTML code. In the next example, you will see a small script generating the HTML version of "Hello World".

<html>
<head>
    <title>Title of the site</title>
</head>
<body>
    <?php echo 'hello world<br>'; ?>
</body>
</html>

As you can see, the PHP code is included in the HTML code. <?php tells the server that the PHP interpreter has to be started here. In the example you can see that parts of the document are static and other parts of the document are created dynamically by PHP.

Another way to obtain the same target would be to generate the entire document dynamically. This will be slower than the version you have just seen, but in some cases it makes sense or is necessary to generate everything dynamically. Let's have a look at the following code:

<?php
    echo '<html>
        <head>
        <title>Title of the site</title> '.
       '</head>';
    echo "<body>hello world<br></body></html>\n";
?>

The first echo command consists of two parts. The first three lines can be found between two single quotes. PHP recognizes that the command continues in the next line and does not end in the first line of the echo command. This way multiple lines can be treated as one command. Another way is to use a string operation as you can see at the end of line number 3 of the echo command. After the single quote, we use a point to tell PHP that the first string, which has just ended, has to be connected with the next string. In this case the second string is </head>. All components of the first echo command are passed to PHP in single quotes.

The second echo command contains the text we want to be displayed on the screen. This time we pass the text to echo using double quotes. Using single quotes or double quotes makes a significant difference: Single quotes are used to pass static text to PHP. Using double quotes allows you to use variables within the string. Knowing this difference is important because otherwise you might run into trouble. When executing the script you have just seen, the result will be a simple HTML document:

<html>
        <head>
        <title>Title of the site</title> 
        </head>
        <body>hello world<br></body>
</html>

The HTML is still not more than a simple "Hello World" application, but it is already HTML code.

3.1.2 Variables

Variables are a core component of almost every programming language available, and without variables it would be impossible to write useful applications. The idea behind variables is to have a language component that can have different values assigned to it. It is also possible to use variables as containers for storing data that is used in many different places in your application. Let's imagine an example where you want to display the same text on the screen twice:

<?php
    $text="hello world";
 
    echo '<html><head><title>Title of the site</title></head><body>';
    echo "$text<br>";
    echo "$text<br>";
    echo '</body></html>';
?>

First, you assign the string you want to be displayed on the screen to the variable called text. In the next step some HTML code is generated and the variable is printed on the screen twice. Keep in mind that we have to use double quotes instead of single quotes; otherwise, the result would be:

$text
$text

With single quotes, variables cannot be used within a string, so the result is not what you want it to be.

Figure 3.1 shows what comes out when you look at the result using Mozilla.

Figure 3.1Figure 3.1 A more sophisticated version of Hello World.

3.1.3 Adding Comments

Documentation is nearly as important as the code of a program. Nowadays only 10% of all costs of producing a software product are used for writing the source code. The remaining 90% are used for maintaining the product (this information is provided by the University of Vienna). To reduce the costs of maintaining a product and to reduce the time required to become familiar with the source code, it is essential to add comments to your programs. PHP provides some simple ways to add comments to a program:

<?php
    // this is a comment
    /* a C-style comment */
    echo 'hello world';
?>

In PHP comments can be added to the code as in C and C++. // tells the interpreter that the entire line should not be executed. /* */ is the old C style, which is also supported by PHP. C-style comments can be used to insert commands consisting of multiple lines:

<?php
    /*
     a C-style comment
     which is longer than just one line.
    */
?>

We recommend making heavy use of comments to make your code clearer and easier to understand. Especially if you are not the only one who will have to work with the code, comments will make your daily life much easier.

3.1.4 Executing PHP from the Command Line

In many cases it is useful to execute PHP code from the command line instead of executing the script by starting it using a Web browser.

Let's return to the three-liner called hello.php that we discussed at the beginning of this chapter:

<?php
    echo 'hello world<br>';
?>

To execute a script using a shell command, try the following:

[hs@athlon test]$ php ./hello.php
X-Powered-By: PHP/4.0.4pl1
Content-type: text/html
 
hello world<br>

As you can see, PHP produces more output than just "hello world". The additional information created by PHP defines which output has been created by PHP. In this case it is text/html. To make sure that the entire output is sent to standard output and not to standard error, we redirect all errors returned by PHP and see what comes out:

[hs@athlon test]$ php ./hello.php 2> /dev/null
X-Powered-By: PHP/4.0.4pl1
Content-type: text/html
 
hello world<br>

The result is still the same, and this shows that no errors have occurred.

PHP provides a lot of command-line parameters that can make daily life with the language much easier:

[hs@athlon test]$ php -h
Usage: php [-q] [-h] [-s] [-v] [-i] [-f <file>] | {<file> [args...]}
 -q       Quiet-mode. Suppress HTTP Header output.
 -s       Display colour syntax highlighted source.
 -f<file>    Parse <file>. Implies ´-q'
 -v       Version number
 -c<path>    Look for php.ini file in this directory
 -a       Run interactively
 -d foo[=bar]  Define INI entry foo with value 'bar'
 -e       Generate extended information for debugger/profiler
 -z<file>    Load Zend extension <file>.
 -l       Syntax check only (lint)
 -m       Show compiled in modules
 -i       PHP information
 -h       This help

As you can see, PHP provides a lot of options you can use from the command line directly. Many developers use only a Web browser to build and to debug PHP applications. Using PHP's command-line parameters can make life much easier; we strongly recommend making heavy use of these features.

One of the most important command-line flags is the -m flag, which you can use to ask PHP which modules have been compiled. This is extremely important if you have not compiled PHP yourself or if you no longer know which modules you added at compile time:

[hs@athlon test]$ php -m
Running PHP 4.0.4pl1
Zend Engine v1.0.4, Copyright (c) 1998-2000 Zend Technologies
 
[PHP Modules]
imap
ldap
mysql
pgsql
zlib
yp
xml
wddx
sysvshm
sysvsem
standard
sockets
session
posix
pcre
gettext
gd
ftp
dba
 
[Zend Modules]

As you can see, the standard PHP distribution included in Red Hat 7.1 supports a lot of modules. You will learn about many of these modules in this book, which will guide you through the details of these modules. One module you will have a very close look at is the pgsql module, which is responsible for interacting with PostgreSQL databases.

An important command-line flag of the PHP interpreter is the -i flag, which can be used to generate information about PHP itself. To generate the result, you can use the following:

[hs@athlon test]$ php -i > /tmp/phpinfo.html

The HTML file that has been generated is very long, so it is not included here.

3.2 Control Structures and Operators

Usually programs need so-called control structures, which are used to decide at runtime what a program has to do. Flow control is an important part of every programming language and is essential for building applications. PHP provides a broad range of methods, as you will see in this section.

3.2.1 Operator and IF/ELSE/ELSEIF Statements

Use if to check whether a certain expression is true or not. If is supported by all commonly used programming languages such as C/C++, Java, Perl, and Python, and therefore it is a fundamental instrument of every computer programmer. To show you how conditions can be checked using if, we include a short example:

<?php
    if   (2 > 1)
    {
        echo '2 is higher than 1<br>';
    }
?>

A message will be displayed on the screen because 2 is higher than 1. If the condition wasn't fulfilled, nothing would be displayed.

NOTE

If an empty document is returned by PHP, an error will be raised by some browsers.

Normally if is used to decide whether or not something has to be done. If a certain condition is fulfilled, PHP will execute the code in parentheses, but what has to be done if a condition is not fulfilled? If is very often used in combination with else. Every time an expression in the if statement returns false, the code of the else branch will be executed. Using if in combination with else is an extremely comfortable feature because it makes programming much easier and helps you to avoid bugs. In the next example you will learn how to use if and else:

<?php
    $a=23;
    $b=34;
 
    if   ($a > $b)
    {
        echo 'a is higher than b';
    }
    else
    {
        echo 'b is higher than a';
    }
?>

First, we initialize two variables. $a is set to 23 and 34 is assigned to $b. In the next step we check if $a is higher than $b. If the expression returns true, a is higher than b will be displayed on the screen. Otherwise, b is higher than a will be the result of the program.

In the next example you will see what you can do if you want a message to be displayed if $b is higher than $a and $b is higher than 30:

<?php
    $a=23;
    $b=34;
 
    if   ($a > $b)
    {
        echo 'a is higher than b';
    }
    else
    {
        if   ($b > 30)
        {
            echo 'b is higher than a and higher than 30.';
        }
    }
?>

$a is lower than $b, so PHP will execute the else branch. In the else branch you use a second if statement to find out if $b is higher than 30. It is an easy task to solve the problem the way it is shown in the previous example, but it is not the most elegant way:

<?php
    $a=23;
    $b=34;
 
    if   ($a > $b)
    {
        echo 'a is higher than b';
    }
    elseif ($b > 30)
    {
        echo 'b is higher than a and higher than 30.';
    }
?>

Instead of using a second if statement in the else branch, it is also possible to use elseif, which is in most cases the shorter and more elegant way.

Sometimes it is necessary to find out if two or more conditions are fulfilled. Therefore multiple expressions can be combined using operators and parentheses. Assume that you want to check whether $a is higher than 10 but lower than 50:

<?php
    $a=23;
 
    if   ($a > 10 && $a < 50)
    {
        echo "$a higher than 10 and lower than 50";
    }
?>

You can use the && operator to tell PHP that both conditions have to be fulfilled; otherwise, false will be returned and the else branch, which does not exist in our example, will be executed. && is equal to and, so it does not matter if we use ($a > 10 and $a < 50) or ($a > 10 && $a < 50) in our example. Using && instead of and is the more common way because && is also supported by programming languages like C/C++ and Perl. If you execute the example, the result will be 23 higher than 10 and lower than 50.

The counterpart of and is the or operator. If or is used, true will be returned if one expression returns true. Let's have a look at an example:

<?php
    $a=2;
 
    if   ($a > 10 || $a < 50)
    {
        echo "$a higher than 10 or lower than 50";
    }
?>

You want a string to be printed on the screen if $a is either higher than 10 or lower than 50. If one of those conditions is fulfilled, the string will be displayed. The number 2 is not higher than 10 but lower than 50, so we can find 2 higher than 10 or lower than 50 printed on the screen. Instead of || you can also use or.

Another important operator is the xor operator. False is returned if both values are the same; otherwise, the result is true. The next example demonstrates the usage of xor.

<?php
    $a=18;
    $b=19;
 
    if   ($a xor $b)
    {
        echo '$a and $b are the same';
    }
    else
    {
        echo '$a and $b are not the same';
    }
?>

As you might have expected, $a and $b are not the same is returned by the script.

So far, you have learned to use &&, ||, and xor. Now it is time to use these operators as a team to build more complex expressions. Assume that you want a string to be displayed if $a is higher than 10 and lower than 20 or exactly 2. In this case it is necessary to group expressions:

<?php
    $a=2;
 
    if   (($a > 10 && $a < 20) || $a == 2)
    {
        echo "$a higher than 10 but lower than 20 or exactly 2";
    }
?>

The first expression consists of two parts, which are connected using &&. If all expressions in parentheses are fulfilled, the first part will return true. If either the first or the second part of the entire expression returns true, the result will be true. In your case the second part of the expression is an exact match, so the entire expression is true.

Those among you who haven't done a lot of computer programming yet might wonder why == is used instead of = in the example you have just seen. It is not a typo. == is used to check whether two variables are the same. =, however, is used to find out whether a variable can be assigned to another variable. Let's have a look at a very simple example:

<?php
    $a=18;
 
    if   ($a = $b)
    {
        echo '$a can be assigned to $b';
    }
    else
    {
        echo '$a cannot be assigned to $b';
    }
?>

First, a value is assigned to $a. In the next step you try to find out if $b can be assigned to $a. Therefore you have to use the = operator. Because $b hasn't been used yet, the else branch will be executed.

If statements can also be used to find out whether a variable has already been defined. As you will see in the section called "Working with Forms," later in this chapter, checking variables is essential for every PHP program. The next example shows how you can find out whether a variable has already been in use:

<?php
    if   ($a)
    {
        echo '$a has already been defined';
    }
    else
    {
        echo '$a has not been defined yet';
    }
?>

In this case the result will be $a has not been defined yet because $a has not been used before.

3.2.2 WHILE and DO..WHILE

WHILE loops are very widespread in programming languages. Like almost all other programming languages, PHP provides WHILE loops, but what are WHILE loops good for? WHILE loops are used to execute a piece of code multiple times. Here is an example of a simple WHILE loop:

<?php
    echo '<html><body>';
 
    $a=1;
 
    while  ($a <= 5)
    {
        echo "a: $a<br>\n";
        $a++;
    }
    echo '</body></html>';
?>

The numbers from one to five are displayed. First, some HTML code is generated. In the next step we set $a to 1 and start the loop. The code between the curly brackets has to be executed until $a is higher than 5. Every time the loop is processed, a: and the content of $a are displayed on the screen. After that $a is incremented by one. The ++ operator is very often used in languages like C and C++. As you can see, it is also available in PHP. $a++ is equal to $a=$a+1.

Let's have a look at what is displayed in the browser when we execute the script:

a: 1
a: 2
a: 3
a: 4
a: 5

As we have promised, the numbers from 1 to 5 are displayed. The HTML code you generated will not be displayed on the screen because it is used only by the browser.

The syntax that has just been described is the most commonly used way of using WHILE loops. However, PHP provides an additional way of using WHILE:

<?php
    echo '<html><body>';
 
    $a=1;
 
    while  ($a <= 5):
        echo "a: $a<br>\n";
        $a++;
    endwhile;
    echo '</body></html>';
?>

The code shown in the preceding listing is equal to the code you have seen before. The only difference is the way WHILE is used. In the second example you don't use curly brackets, so you have to tell PHP when the loop ends. This is done using endwhile.

If you are using loops, make sure that the condition that makes the loop stop will be false after executing the loop for the desired number of times; otherwise, the loop will run until one of the components (PHP, the kernel, the Web server, and so forth) stops the execution of the script. In your case you'd have an endless loop if $a was never incremented. Endless loops are very dangerous and you have to keep that in mind. PHP offers an option in php.ini to limit both the memory consumption and runtime of a PHP script. We highly recommend setting these options to a reasonable value.

Sometimes it is necessary to execute the code of a loop once and to check the condition for stopping the loop after that. For that PHP offers do..while loops:

<?php
    echo '<html><body>';
 
    $a=6;
 
    do
    {
        echo "a: $a<br>\n";
    }
    while  ($a <= 5);
    echo '</body></html>';
?>

First, 6 is assigned to $a, and then we start the loop using do. $a, which is 6, is displayed on the screen and you check if the loop has to be executed again. Because 6 is higher than 5, the echo command won't be executed again. In this case you are lucky because if $a was lower than 6, you'd run into an infinite loop. $a is not increased, so ($a <= 5) would always be true.

What can you do if you have to leave a loop in the middle of a block? PHP has the right solution for you. Break is a command that can be used to stop all kinds of loops in the middle of a block. Here is an example:

<?php
    echo '<html><body>';
 
    $a=1;
 
    do
    {
        echo "a: $a<br>\n";
        $a++;
        if   ($a == 3)
        {
            break;
        }
    }
    while  ($a <= 5);
    echo '</body></html>';
?>

You want to execute the loop as long as $a is lower than 6, but if $a is equal to 3, you want to exit the while loop.

If you execute the script, you can see the result in the browser:

a: 1
a: 2

Two lines will be displayed because the loop is interrupted after printing two lines on the screen.

Continue is another important keyword when dealing with loops. Continue is used to stop the execution of a block without leaving the loop. The idea is to ignore steps in the loop. Here is an example:

<?php
    echo '<html><body>';
 
    $counter=0;
    $test=10;
    while ($counter < $test)
    {
        if   ($counter %2)
        {
            $counter++;
            continue;
        }
        echo "Current value of counter: $counter<br>";
        $counter++;
    }
 
    echo '</body></html>';
?>

The loop is executed until $counter is equal to $test. In the loop you try to find out if $counter can be divided by two. If the result is different from 0 (in your case if it is 1), increment the counter and use continue. The program will start to check the condition again and if it is still true, the block will be executed again.

The output of the script is not surprising:

Current value of counter: 0
Current value of counter: 2
Current value of counter: 4
Current value of counter: 6
Current value of counter: 8

One line is generated for every second number the loop is processed for.

Continue can also be used to leave more than just one loop. Let's have a look at the next example:

<?php
    echo '<html><body>';
 
    $counter=0;
    while ($counter == 0)
    {
        $counter++;
        $inner=0;
        while  ($inner == 0)
        {
            $inner++;
            continue 2;
            echo "inner<br>";
        }
        echo "middle<br>";
    }
    echo "outer<br>";
 
    echo '</body></html>';
?>

You can see two while loops. Every loop is entered, but in the inner loop you call continue with a parameter to tell PHP how many loops have to be left. In this case you tell PHP to leave two loops, so the result is outer. Nothing else is displayed on the screen. Very efficient applications can be built by using continue with parameters, but this is also very dangerous because a programmer can easily lose the overview of the logic flow of the source code.

3.2.3 FOR

If a block has to be executed a fixed number of times, it is recommended to use for loops instead of while loops.

A for loop consists of a starting value, a condition that is checked every time the loop is processed, and an expression that is executed after every time the loop is processed. Let's have a look at an example:

<?php
    echo '<html><body>';
 
    for($i = 0; $i < 5; $i++)
    {
        echo "i: $i<br>\n";
    }
 
    echo '</body></html>';
?>

You want to display the numbers from 0 to 4 on the screen. Therefore a for loop has been implemented in the script. The loop starts with $i being 0 and it is executed as long as $i is lower than 5. The third parameter tells PHP to increment $i after every time the loop is processed. The output of the script shows what comes out when you start the program using a Web browser.

i: 0
i: 1
i: 2
i: 3
i: 4

Sometimes it is necessary to implement more powerful and more complex for loops. Just as in many other languages like C or C++, a list of conditions can be used in combination with for loops. This feature is very important because it allows you to implement complex features with little effort:

<?php
    echo '<html><body>';
 
    for($i = 0, $j = 10; $i < 5, $j > 0; $i++, $j = $j - 2)
    {
        echo "i: $i --- j: $j<br>\n";
    }
 
    echo '</body></html>';
?>

All three parameters consist of a list of expressions used to process a certain variable. The text generated by the program shows what has happened to the variables in the program:

i: 0 --- j: 10
i: 1 --- j: 8
i: 2 --- j: 6
i: 3 --- j: 4
i: 4 --- j: 2

$i was incremented by one, whereas $j was reduced by two every time the loop was processed. Using the syntax you have just seen allows you to treat multiple variables using just one for loop. The list of operations used in the loop can easily be extended to the desired complexity.

Up to now, you have learned to use for loops with a list of expressions. However, in PHP, programmers are not forced to provide a list of at least one parameter because it is also possible to leave the list empty, as shown in the following example:

<?php
    echo '<html><body>';
 
    $i=0;
    for   (; $i < 5; )
    {
        echo "i: $i<br>\n";
        $i++;
    }
 
    echo '</body></html>';
?>

The first and the third parameter of the for loop are empty. The result of the loop is still a list of all numbers from 0 to 4, but it has been generated differently. $i is initialized in the line before the loop starts and it is incremented after displaying the output on the screen:

i: 0
i: 1
i: 2
i: 3
i: 4

As you can see, there are many ways to solve the problem because PHP has a comparatively rich syntax. For those of you out there who are interested in writing very short and efficient code, the next example might be of interest:

<?php
    echo '<html><body>';
    for   ($i = 0; $i < 5; print "i: $i<br>", $i++);
    echo '</body></html>';
?>

The output of the script is still the same, but we needed only one line to print the numbers on the screen. As you can see, PHP allows you to use any kind of expressions in a for loop, which makes that kind of loop extremely flexible.

3.2.4 SWITCH

To avoid long sequences of if statements, it is sometimes possible to use switch and case statements instead. Switch and case are often used to find the right piece of code that has to be executed from a list of possibilities. Let's have a look at the next example:

<?php
    $a=2;
 
    switch ($a)
    {
        case 1:
            echo "case 1: \$a is $a<br>";
            break;
        case 2:
            echo "case 2: \$a is $a<br>";
            break;
        case 3:
            echo "case 3: \$a is $a<br>";
            break;
    }
?>

First, 2 is assigned to $a. The switch statement checks all cases and if the right value is found, the branch is entered and PHP executes all the code until a break command is found. If you execute the script, one line will be displayed:

case 2: $a is 2

The same result can also be achieved by using if statements instead of switch and case:

<?php
    $a=2;
 
    if   ($a == 1)
    {
            echo "case 1: \$a is $a<br>";
    }
    if   ($a == 2)
    {
            echo "case 2: \$a is $a<br>";
    }
    if   ($a == 3)
    {
            echo "case 3: \$a is $a<br>";
    }
?>

You can print the string $a on the screen. The $ character has to be escaped using a backslash because otherwise PHP would display the content of the variable $a instead of the string $a on the screen.

In the next step you will try to use switch and case without using break as well:

<?php
    $a=2;
 
    switch ($a)
    {
        case 1:
            echo "case 1: \$a is $a<br>";
        case 2:
            echo "case 2: \$a is $a<br>";
        case 3:
            echo "case 3: \$a is $a<br>";
    }
?>

The result of the version using no break commands differs significantly, as you can see in the following example:

case 2: $a is 2
case 3: $a is 2

All of a sudden two lines are returned and that is definitely not the result you want. PHP searches for the right value and executes the code until a break command is found. In your case no break commands are in the code, so it is executed until the end. In some cases this might be the desired behavior of the program, but in most cases it is not.

Another feature of switch and case is the ability to handle default values. If no value in the list matches, PHP will execute the default branch. In the following example, you are looking for 9, but 9 is not listed in the switch statement:

<?php
    $a=9;
 
    switch ($a)
    {
        case 1:
            echo "case 1: \$a is $a<br>";
            break;
        case 2:
            echo "case 2: \$a is $a<br>";
            break;
        default:
            echo "the value couldn't be found<br>";
    }
?>

PHP will execute the default code because 9 has not been found in the list:

the value couldn't be found

As we have already mentioned, you can make a workaround using if statements instead of switch and case, but this can be far more complex especially when default values are involved and some of your branches do not contain break statements. Let's have a look at the next example. The target is to display 1 and 2 on the screen if the switch statement is called with $a being 1. In all other cases, only the value switch is called with should be displayed:

<?php
    $a=1;
 
    switch ($a)
    {
        case 1:
            echo '1<br>';
        case 2:
            echo '2<br>';
            break;
        case 3:
            echo '3<br>';
            break;
        default:
            echo 'default';
    }
?>

The task is easy because the only thing you have to do is to write a switch block where every entry but the first one contains a break command.

Switch and case constructions are a very flexible and powerful feature of PHP. It is possible to build sophisticated applications without having to use complex if/else constructs.

3.3 Data Types and Functions

In the previous sections you have already seen that PHP supports variables, but so far you have only learned to use numbers and strings. Just like control structures, data types are a core component of every programming language.

Like most other high-level languages, PHP works to a large extent without types and tries to recognize the data type of a variable by itself. However, PHP provides a set of different data types, as shown in Table 3.1.

Table 3.1 Data Types in PHP

Data Type

Description

Int, integer

Numeric values with no commas

Double, real

Floating-point number

String

A sequence of characters

Array

A pool of values

Object

A artificial, user-defined data type


In this section you will learn to use these data types efficiently.

3.3.1 Variables and Names

As you have already seen in the examples discussed in the previous sections, variables are marked with $ in PHP. Unlike Perl, PHP marks all variables with a $ and does not use @ and % as symbols.

In PHP the names of variables are case sensitive, which means that it makes a difference whether a name is written in capital letters. The name of a variable may start with a letter or an underscore. After the first character, all letters and numbers as well as underscores are allowed. However, we strongly recommend using only letters in the variable name because otherwise programs can be confusing and hard to understand, especially when people start mixing up variables written in either capital letters or lowercase letters.

The next example shows that $a is not equal to $A:

<?php
    $a = "I am a string";
    $A = "I am a string as well";
 
    echo "a: $a; A: $A<br>\n";
?>

As you can see, in the result, the two strings are not the same.

a: I am a string; A: I am a string as well

3.3.2 Automatic Data Type Recognition

When a variable has to be processed by PHP, the interpreter follows some predefined rules in order to recognize which data type a variable has:

Knowing these three rules will make it easy for you to forecast the result of an operation and will make it easier for you to write bug-free applications.

3.3.3 Checking Data Types and Explicit Casting

Sometimes it is necessary to change the data type of a variable explicitly. Although PHP does a lot of type casting internally, it might help in some cases to make sure that a variable is assigned to a certain data type. To perform operations like that, PHP provides the required functions. Before you learn about these functions, you will see how you can find the data type of a variable:

<?php
    $a = 3.14159;
    $b = 12;
    $c = "I am a string";
    $d = array(1, 2, 3);
 
    echo '$a is a '.gettype($a)." value<br>\n";
    echo '$b is an '.gettype($b)." value<br>\n";
    echo '$c is a '.gettype($c)." value<br>\n";
    echo '$d is an '.gettype($d)." value<br>\n";
?>

With the help of a function called gettype, it is possible to retrieve the data type of a variable easily. If you use the rules described in the previous section, it will be easy to predict the result of the script:

$a is a double value
$b is an integer value
$c is a string value
$d is an array value

The first value is a floating-point value because it contains a comma. The second value is an integer value because it does not contain a comma. The third value is enclosed by quotes and therefore it is treated as a string. The last value is an array because the expression on the right side of the = returns an array of integer values.

Another way to check the data type of a variable is to use a special, data type–specific function as shown following:

<?php
    $a = 3.14159;
    $b = 12;
    $c = "I am a string";
    $d = array(1, 2, 3);
 
    echo '$a: '.is_double($a)."<br>\n";
    echo '$b: '.is_integer($b)."<br>\n";
    echo '$c: '.is_string($c)."<br>\n";
    echo '$d: '.is_array($d)."<br>\n";
    echo '$d: '.is_object($d)."<br>\n";
?>

You use the functions is_double, is_integer, is_string, is_array, and is_object. If the value passed to the function has the appropriate data type, 1 will be returned. The next listing contains the result of the script you have just seen:

$a: 1
$b: 1
$c: 1
$d: 1
$d: 

All values but the last one are true. The last line shows that $d is not an object.

If you perform an explicit cast, it can easily happen that some of the data stored in the variable you want to cast is lost. This is not a weak point of PHP because casting cannot be done differently by the PHP interpreter. Let's have a look at the next example:

<?php
    $a = 3.14159;
    $b = 12;
 
    $a_cast = (int)$a;
    $b_cast = (double)$b;
 
    echo "a_cast: $a_cast<br>";
    echo "b_cast: $b_cast<br>";
?>

$a is a floating-point number that is cast to integer and displayed on the screen. $b is cast to double and displayed on the screen as well. If you have a look at the result, you will see that $a_cast is not as precise as $a_cast because an integer value is not allowed to store digits right of the comma. $b_cast and $b are the same because integers can also be represented as double values without losing data:

a_cast: 3
b_cast: 12

Some general rules and hints should be taken into consideration when performing casts. Table 3.2 contains a compilation of the most important information concerning casts.

Table 3.2 Rules in PHP

Data Type of Result

Data Type Before the Cast

Changes

Integer

Double

Data right of the point is silently omitted—the value is not rounded.

Integer

String

If no number is recognized, 0 is returned.

Double

Integer

No changes.

Double

String

If no number is recognized, 0 is returned.

String

Integer

Returns the number as a sequence of characters.

String

Double

Returns the number as a sequence of characters.

Array

Object

Will be transformed directly.

Array

Integer

An array of integer values will be created.

Array

String

An array of string values will be created.

Array

Double

An array of floating-point values will be created.

Object

Array

Will be transformed directly.

Object

Integer

An object with the same properties as an integer value is generated.

Object

String

An object with the same properties as a string value is generated.

Object

Double

An object with the same properties as a double value is generated.


From this table, you can easily see which dangers you might have to face when performing typecast operations.

3.3.4 Functions

Functions are the heart of every programming language. They are used to isolate certain tasks of a program and help the programmer to use the same code in various places without having to copy it. Functions can be called with parameters and perform a fixed set of instructions. If necessary, a function can return values to the function or object that has called it.

You have already worked with functions. One of the functions you have dealt with is called gettype, and it returns the data type of a variable. This function is a good example of what the topic is all about. You pass a variable to it and a value will be returned.

In recent years, the word function has lost popularity because in the object-oriented programming paradigm, it no longer exists. As you will see in the chapter about object-oriented PHP (see Chapter 4, "Object-Oriented PHP"), functions are called methods in object-oriented PHP. This makes no difference in the way things work—it is just a new name for an old and useful invention.

3.3.5 Output Functions and Working with Strings

Like Pascal, a programming language defined by Prof. Niklaus Wirth at the Eidgenössische Technische Hochschule (ETH) Zürich in 1970, PHP supports a data type called string. Strings are a sequence of characters and are often used to store text. Unlike in C/C++, handling strings is an easy task in PHP because the programmer does not have to take care of memory management and segmentation faults that occur because of problems with memory allocation. This makes PHP suitable for fast and reliable software development.

The list of functions for working with strings in PHP seems to be endless. We will try to cover the most important ones in this section.

To display ASCII characters on the screen, PHP provides a function called chr. Simply pass the ASCII code to the function, and the desired character will be returned. The next example shows how the e-mail address of one of the authors can "easily" be displayed using chr.

<?php
    echo chr(104).chr(115).chr(64).chr(99).chr(121).chr(98).
        chr(101).chr(114).chr(116).chr(101),chr(99).chr(46).
        chr(97).chr(116)."<br>\n";
?>

And the result is

hs@cybertec.at

I am sure that there are more efficient ways of displaying e-mail addresses; normally chr is used to display characters that cannot be found on the keyboard.

The exact opposite of the chr is the Ord function, which can be used to compute the ASCII value of a character:

<?php
    $a = "a";
    echo Ord($a);
?>

Nowadays encrypting data is an extremely important task because security standards are increasing and hackers might threaten your networks. With the arrival of all those viruses spreading themselves over networks, security has become an important topic. In the next example you will see how a string can easily be encrypted using PHP's onboard functions:

<?php
    $a = "I am a string";
    echo crypt($a);
?>

Simply pass the string you want to process to the crypt function and the result will be encoded using the DES algorithm.

The result will be a string that you won't be able to read:

i34vSr3Aueg2A

As you have already seen, HTML code is a pool of special characters having a certain meaning. A good example for that is the < character, which is used to define the starting point of an HTML tag. The problem is: what can you do when you want to display a < character on the screen? The problem can easily be solved using a function called htmlspecialchars, which converts all characters having a certain meaning or which are not allowed to be used in the appropriate HTML code. The next piece of code shows how this works:

<?php
    $b = "1 > 0";
    echo htmlspecialchars($b);
?>

1 > 0 is displayed on the screen, but the HTML code generated by PHP looks slightly different:

1 &gt; 0

> has been substituted for &gt; and that's what you wanted it to be.

Another important character in the list of special symbols is the & symbol. In HTML code & has to be coded as &amp;. As you can see, in the next example, the htmlspecialchars function takes care of that issue:

<?php
    $b = "Mr. Schönig & Mr. Müller are from Austria";
    echo htmlspecialchars($b)." <br>\n";
?>

If you have a look at the HTML code you have generated, you can see that the ampersand has been replaced for &amp;.

Mr. Schönig &amp; Mr. Müller are from Austria <br>

printf is the dinosaur of string and text processing. It allows you to display formatted text on the screen. The C programmers among you might already be familiar with printf. The PHP version of printf is very similar to the C function. Let's have a look at an example:

<?php
    $a = "Hans";
    printf ("This is the diary of %s.<br>\n", $a);
 
    $b = 23;
    printf ("He is %d years old.<br>\n", $b);
    printf ("$b can also be written as %b (binary) or %o (octal).<br>", 
        $b, $b);
    printf ("Let's print $b again but this time as an integer ".
        "printed as a character: %c.<br>", $b, $b);
 
    $b += 2/12;
    printf ("To be more precise: %s is $b years and two months old; ".
        "as a floating point number this would be: %5.3f.<br>\n",
        
?>

In the first line you define a variable containing the first name of the author. In the next line you want to display this variable as part of a string on the text. Therefore you use printf. %s is substituted for $a. $a is interpreted as a string and will be displayed on the screen as a string. In the next step $b is defined as an integer value. After that $b is displayed as integer value by using %d. In the next line $b is displayed as a binary and as an octal value. This is the first time you use printf with more than just one parameter. Because two substitutions are performed, it is necessary to pass two parameters to printf.

One line later, you try to interpret $b as an integer value printed as a character. In other words, you try to display the character having $b as its ASCII value on the screen.

Finally, you add 2/12 to $b ($b += 2/12 is equal to $b = $b + 2/12) and display $b as a floating-point number using %f. The floating-point number has a total length of five digits, and three of these digits have to be on the right side of the point.

When executing the script, you will receive the this result:

This is the diary of Hans.
He is 23 years old.
23 can also be written as 10111 (binary) or 27 (octal).
Let's print 23 again but this time as an integer printed as a character: #.
To be more precise: Hans is 23.166666666667 years and two months old; 
as a floating point number this would be: 23.167.

Printf supports a lot of formatting instructions. Table 3.3 contains a list of shortcuts supported by printf.

Table 3.3 Formats Accepted by printf

Formatting

Meaning

%b

Interpret value as an integer but print it as a binary value.

%c

Interpret value as an integer but print it as a character.

%d

Interpret value as an integer but print it as a decimal value.

%f

Interpret value as a double and print it as a floating-point number.

%o

Interpret value as an integer but print it as an octal value.

%s

Interpret and print as a string.

%x

Interpret value as an integer but print it as a hexadecimal value using lowercase letters.

%X

Interpret value as an integer but print it as a hexadecimal value using uppercase letters.


Printf returns 0 or 1 depending on whether the command has been executed successfully. If you want to retrieve the string generated by printf, you have to use sprintf instead. In contrast to printf, sprintf returns the string that has been generated and does not print it on the screen. Here is an example:

<?php
    $a = "Hans";
    $result = sprintf ("This is the diary of %s.", $a);
    echo "Result: $result<br>\n";
?>

This time the result is assigned to a variable called result and displayed on the screen using echo.

If you want a backslash to be put before every ., \\, +, *, ?, [, ^, ], (, $, or ), you can use the QuoteMeta function. Especially when building interfaces to other software products or when working with regular expressions, this function might be of interest for you because it helps you to escape special characters.

Here is an example of how the function can be used:

<?php
    $a = "Is 1+2*3=7?";
    $result = QuoteMeta ($a);
    echo "$result";
?>

The result will contain many backslashes:

Is 1\+2\*3=7\?

If you want to remove the backslashes inserted by QuoteMeta, you can use the stripslashes function.

strcmp can be used to compare strings and is another function that has been borrowed from C. The usage of strcmp in PHP is very similar to that of C, as you can see in the following example:

<?php
    $a = "abc";
    $b = "bcd";
 
    echo strcmp($a, $b)."<br>";
    echo strcmp($b, $a)."<br>";
    echo strcmp($a, $a)."<br>";
?>

In the first two lines variables are defined, which will be compared with each other in the next three lines. The first strcmp command returns -1 because the two variables are passed to the function in alphabetical order. The parameters are passed to the second command in reverse order, so 1 is returned. If both values are equal, strcmp will return 0. In the following lines, you can see the output of the script.

-1
1
0

The strlen function is widely used and can be taken to compute the length of a string. First, a string called $a is defined. In the next step, the length of this string is computed and displayed on the screen.

<?php
    $a = "This is a string";
    echo strlen($a)."<br>\n";
?>$a

In some cases it might be useful to remove whitespace characters from the beginning and the end of a string. Therefore you can use trim:

<?php
    $b = "   I am a string   ";
    echo 'beginning:'.trim($b).':end';
?>

$b contains a string with a few blanks at the beginning and the end of it. With the help of trim, these blanks can easily be removed:

beginning:I am a string:end

The result no longer contains these blanks. If you only want to remove the blanks on the left edge of the string, ltrim can be used. If the blanks on the right side have to be removed, rtrim will be the right function.

You can convert strings to uppercase letters and vice versa by using two easy-to-use PHP functions called strtoupper and strtolower. In the next example you will see how these functions can be used:

<?php
    $a = "i am a string";
    $b = strtoupper($a);
 
    echo "$b<br>\n";
    echo strtolower($b);
?>

First, a string is defined. In the next step it is converted to uppercase letters and assigned to $b. Finally both strings are displayed on the screen.

I AM A STRING
i am a string

In many cases you don't want to convert all characters to upper- or lowercase letters. With the help of the ucfirst function, it is possible to convert only the first letter to uppercase. Ucwords makes sure that every word in a string starts with an uppercase letter:

<?php
    $a = "i am a string";
 
    echo ucfirst($a)."<br>";
    echo ucwords($a)."<br>";
?>

The output of the script is in no way surprising:

I am a string
I Am A String

PHP supports a lot of functions related to strings and it is beyond the scope of this book to cover all of these functions in detail. We have to decided to mention only the most important and most widely used functions.

3.3.6 Working with One-Dimensional Arrays

The ability to handle arrays easily and efficiently is one of the features that has made PHP so successful in the past few years. Not only can arrays be handled easily, but many functions related to arrays are also available and you will learn about these functions in this section.

Arrays can either be one-dimensional or multidimensional. A one-dimensional array is a data structure used to store a list of values. You have already learned in the section "Data Types and Functions" earlier in this chapter that arrays are one of PHP'S built-in data types. However, arrays are in a way different than data types like integer or double. An array is not an atomic value, which means that it consists of one or more other values, which can be arrays again.

Let's start with an example where you will see how you can find out whether a variable is an array:

<?php
    $a = 12;
    $b = array(23, "Hans", "Vienna", 1.78);
 
    echo "a: ".is_array($a)."<br>";
    echo "b: ".is_array($b);
?>

You can see that an integer value and an array are defined. The array consists of one integer, two strings, and one floating-point value. As you can see, it makes absolutely no difference which values are inserted into an array because it is just a container for storing all kinds of variables. When executing the script, you can see that is_array returns 1 if the variable passed to it is an array:

a:
b: 1

Now that you have learned to create arrays and to find out if a variable is an array, you will learn to access the components of an array. The first thing to know is to find out how many values are stored in an array. This can be done by using the count function. As soon as you know the number of components of your array, it is an easy task to display the content of the array on the screen:

<?php
    $a = array(23, "Hans", "Vienna", 1.78);
 
    $vals = count($a);
    echo "Number of values in the array: $vals<br><br>\n";
 
    for   ($i = 0; $i < $vals; $i++)
    {
        echo "Value number $i: $a[$i]<br>";
    }
?>

The output of the script shows that four records were found in the array. Finally all records are displayed on the screen. The various cells of the array are accessed by using parentheses and the index of the value:

Number of values in the array: 4

Value number 0: 23
Value number 1: Hans
Value number 2: Vienna
Value number 3: 1.78

Displaying all records on the screen can also be done differently:

<?php
    $a = array(23, "Hans", "Vienna", 1.78);
 
    foreach ($a as $x)
    {
        echo "$x<br>";
    }
?>

After defining the array, a loop is entered that is executed for every value in the array. Every value in $a is assigned to $x, which is displayed on the screen using an echo command:

23
Hans
Vienna
1.78

An array does not have to be consecutively numbered. In many cases it is helpful to use strings to identify the values in an array:

<?php
    $a = array(age => 23, name => "Hans", residence => "Vienna", 
        height => 1.78);
 
    foreach ($a as $x)
    {
        echo "$x<br>";
    }
?>

In the preceding example, an associative array is initialized and the content is displayed on the screen as shown in the next listing:

23
Hans
Vienna
1.78

Many of you might have dealt with associative arrays already in Perl. In PHP things work pretty much the same way as in Perl. An associative array is just an array indexed with strings. The idea is to be able to store every data type in an array and to index it with anything you like.

Retrieving data from an associative array can be done as you have seen for arrays indexed with numbers:

<?php
    $a = array(age => 23, name => "Hans", residence => "Vienna", 
        height => 1.78);
 
    echo "Age: ".$a["age"]." years <br>";
    echo "Name: ".$a["name"]."<br>";
    echo "Residence: ".$a["residence"]."<br>";
    echo "Height: ".$a["height"]." centimeter<br>";
?>

All values are displayed on the screen:

Age: 23 years
Name: Hans
Residence: Vienna
Height: 1.78 centimeter

In this section we have already mentioned that an array can also contain arrays. The next example shows an array with one element containing an array with two elements:

<?php
    $a = array(name => array("Hans", "Epi"));
    $b = $a["name"];
    echo "$b[0] - $b[1]<br>\n";
?>

You can insert an array into an array just like any other record. The only thing you have to take care of is when retrieving the values again—this is slightly more difficult than if it was just an ordinary value.

If you execute the script, the values you have inserted will be retrieved:

Hans - Epi

With the help of arrays, complex data structures can be built. However, if the data structures become very complex, it is useful to use object-oriented PHP instead of complex arrays and procedures. Object-oriented PHP will be covered extensively in the next chapter of this book.

An important command when working with arrays is the reset command. Unlike what some of you might expect, reset is not used to remove elements from an array but to set the pointer to the first element of an array. If you are working with an array, the pointer might not be on the first element and you will have trouble using commands like next and prev safely. In the next example you will see how to define an array, set the pointer to the first element, and display all records including the keys on the screen:

<?php
    $a = array(23, 16, 8, 99);
 
    reset($a);
 
    while (list ($key, $val) = each ($a))
    {
        echo "$key: $val<br>\n";
    }
?>

As you can see, every value in the array has a key.

0: 23
1: 16
2: 8
3: 99

Finding the key of a value is an important task because the data structure can be indexed using any other variable.

Sorting data is another important operation:

<?php
    $a = array(23, 16, 8, 99);
    sort($a);
 
    foreach ($a as $val)
    {
        echo "val: $val<br>\n";
    }
?>

For building efficient data structures, it is important to sort data before working with it. The output of the script you have just seen is displayed sorted because you have used sort to change the order of the elements.

val: 8
val: 16
val: 23
val: 99

To sort data in a reverse order, use arsort instead of sort:

<?php
    $a = array(23, 16, 8, 99);
    arsort($a);
 
    foreach ($a as $val)
    {
        echo "val: $val<br>\n";
    }
?>

As you can see, the data is now displayed the other way around:

val: 99
val: 23
val: 16
val: 8

The opposite of sorting an array is to use shuffle—a function for putting values in reverse order:

<?php
    $a = range(1, 7);
 
    shuffle($a);
 
    while (list ($key, $val) = each ($a))
    {
        echo "$key: $val<br>\n";
    }
?>

First, you create an array that contains values from 1 to 7 using the range function. In the next step the array is shuffled and all values are displayed on the screen.

0: 3
1: 1
2: 2
3: 4
4: 5
5: 7
6: 6

The values are no longer ordered. Shuffling arrays can be useful for many purposes. Imagine a situation where you want to display records in a random order—shuffle will solve the problem for you.

You have seen how an array can be accessed by using an index or a foreach command. Another way to process all values of an array is to use reset and next. Next sets the pointer to the next value in the array and returns the current value. With the help of a do/while loop, it is an easy task to go through the array:

<?php
    $a = array(23, 16, 8, 99);
 
    reset($a);
 
    $val = $a[0];
    do
    {
        echo "val: $val<br>\n";
    }
    while  ($val = next($a));
?>

As you can see following, all values are displayed on the screen:

val: 23
val: 16
val: 8
val: 99

Stacks are a special kind of array. They are a fundamental data structure and are heavily used by many programmers. If you want to process commands using postfix notation, stacks are an essential instrument. Two operations are defined for stacks: Push adds a value to the stack. Pop returns the last value that was added to the array and removes it from the list—in other words stacks use a LIFO algorithm (LIFO = last in first out).

To make clear what you have just learned, we have included an example:

<?php
    $a = array();
    array_push($a, 'the first value');
    array_push($a, 'the second value');
    array_push($a, 'the third value');
 
    while (list ($key, $val) = each ($a))
    {
        echo "$key: $val<br>\n";
    }
 
    echo "<br>removing: ".array_pop($a)."<br>";
    echo "removing: ".array_pop($a)."<br><br>";
 
    while (list ($key, $val) = each ($a))
    {
        echo "$key: $val<br>\n";
    }
?>

In the first line, an empty array is defined. In the next three lines, values are added to the stack using array_push, and all values are displayed on the screen. Then two values are removed from the stack and displayed on the screen. As you can see, the return value of array_pop is returned and removed from the array. After adding three values to the array and removing two values from the array, one value is left and displayed on the screen:

0: the first value
1: the second value
2: the third value

removing: the third value
removing: the second value

0: the first value

Counting the values of an array can be done by using the array_count_values function. The idea of this function is to compute the frequency with which a value occurs in the array.

Sometimes it is necessary to remove duplicated values from an array. Array_unique will do the job for you:

<?php
    $a = array(23, 23, 12, 9, 23, 9);
    $counted = array_count_values($a);
 
    echo "Return data counted: <br>\n";
    while (list ($key, $val) = each ($counted))
    {
        echo "$key: $val<br>\n";
    }
 
    echo "<br>Return unique data: <br>\n";
    $a = array_unique($a);
    while (list ($key, $val) = each ($a))
    {
        echo "$key: $val<br>\n";
    }
?>

After defining an array containing some value, an array is initialized containing the frequency with which various values in $a occur. In the first column the key is displayed. The second column tells us how often the key was found in the array.

In the next step the array_unique function is used to remove duplicated entries. The key to a value is the position in which a certain value has occurred in the original array. The value 9, for instance, was found on the fourth and the last position of the array. Because this is redundant, the last field in the array has been deleted and only the value in position number 4 remains:

Return data counted:
23: 3
12: 1
9: 2

Return unique data:
0: 23
2: 12
3: 9

The output of the function shows what comes out when the script is executed.

If you are working with more than just one array, it might happen that you have to compare arrays with each other. Therefore PHP provides some powerful and easy-to-use functions. One of the functions is called array_merge and is used to combine two arrays:

<?php
    $a = array(23, 12, 9);
    $b = array(12, 13, 14);
 
    $res = array_merge($a, $b);
 
    while (list ($key, $val) = each ($res))
    {
        echo "$key: $val<br>\n";
    }
?>

Two arrays are defined, which are merged. If you execute the script, the result will contain all values of both arrays as shown in the following listing:

0: 23
1: 12
2: 9
3: 12
4: 13
5: 14

The counterpart of array_merge is the array_diff function, which can be used to compute the difference of two arrays as shown following:

<?php
    $a = array(23, 12, 9);
    $b = array(12, 13, 14);
 
    $res = array_diff($a, $b);
 
    while (list ($key, $val) = each ($res))
    {
        echo "$key: $val<br>\n";
    }
?>

Two values can be found in $a that are not in $b:

0: 23
2: 9

If you want to compute the intersection of two arrays instead of the difference, you can use the array_intersect function. Just like array_diff and array_merge, array_intersect needs to have two arrays passed to it:

<?php
    $a = array(23, 12, 9);
    $b = array(12, 13, 14);
 
    $res = array_intersect($a, $b);
 
    while (list ($key, $val) = each ($res))
    {
        echo "$key: $val<br>\n";
    }
?>

One value is returned:

1: 12
Calculating the sum of all values in an array can be done in many ways 
but the easiest one is to use array_sum:
<?php
    $a = array(23, 12, 9);
    echo array_sum($a);
?>

The resulting value 44 will be displayed on the screen.

Splitting a string and generating an array out of it is an important operation. If you have to process tab-separated files, for instance, splitting strings and generating arrays is an essential procedure. PHP provides a function called explode. Explode has to be called with two parameters. The first one tells PHP where to split the string by defining a pattern. The second parameter contains the variable you want to process.

The counterpart of explode is implode, which does exactly the opposite of explode:

<?php
    $a = "This is a string";
    $b = explode(" ", $a);
 
    while (list ($key, $val) = each ($b))
    {
        echo "$key: $val<br>\n";
    }
 
    $c = implode(" ", $b);
    echo "<br>$c<br>";
?>

At the beginning of the script, a variable is defined that is used to generate an array in the second line. A space character is selected as separator. In the next step the content of $b is displayed on the screen. Finally all values in $b are combined into a string again. Again a blank is chosen as the separator.

If you execute the script, the output will be displayed on the screen:

0: This
1: is
2: a
3: string

This is a string

As you can see in the last line of the result, the array has been combined to the string you have defined in the first line again.

3.3.7 Working with Multidimensional Arrays

Multidimensional arrays are a little bit more difficult to handle than their one-dimensional counterparts. However, with some basic techniques, it is possible to perform complex operations.

Each can be used for processing one-dimensional or multidimensional arrays. Even for more complex data structures, each will play an important role:

<?php
    $a[0][0] = "Rock me Amadeus";
    $a[0][1] = "Jeanny";
    $a[0][2] = "Vienna Calling";
    $a[1][0] = "Satellite to Satellite";
 
    echo "<b>Falco's masterpieces:</b><br>\n";
    while (list ($key, $val) = each ($a))
    {
        echo "$key: $val<br>\n";
    }
?>

In the first four lines, a two-dimensional array is created and four values are assigned to it. The target is to display all records on the screen.

The next listing shows what comes out when you execute the script:

Falco's masterpieces:
0: Array
1: Array

The listing does not contain the desired result because each extracts a list of arrays instead of a list of single values from the multidimensional array. To display the data, you have to make some minor changes in the code:

<?php
    $a[0][0] = "Rock me Amadeus";
    $a[0][1] = "Jeanny";
    $a[0][2] = "Vienna Calling";
    $a[1][0] = "Satellite to Satellite";
 
    echo "<b>Falco's masterpieces:</b><br>\n";
    while (list ($key, $val) = each ($a))
    {
        while (list ($subkey, $subval) = each ($val))
        {
           echo "key:$key - subkey: $subkey - value: $subval<br>\n";
        }
    }
?>

A second loop has to be added to extract all fields from the arrays extracted from the multidimensional array. If you execute the script now, the result will contain all values:

Falco's masterpieces:
key:0 - subkey: 0 - value: Rock me Amadeus
key:0 - subkey: 1 - value: Jeanny
key:0 - subkey: 2 - value: Vienna Calling
key:1 - subkey: 0 - value: Satellite to Satellite

In the next step you want to sort the values in the array. To achieve that target, you can try to add a sort command after assigning the values to the array:

    sort($a);

This won't lead to the desired result because PHP will sort the keys and not the values:

Falco's masterpieces:
key:0 - subkey: 0 - value: Satellite to Satellite
key:1 - subkey: 0 - value: Rock me Amadeus
key:1 - subkey: 1 - value: Jeanny
key:1 - subkey: 2 - value: Vienna Calling

If you want to sort the content of the array and not the keys, you have to build a multidimensional array where all axes have the same amount of values. In your case you can build a matrix with four values (2x2 matrix):

$a[0][0] = "Rock me Amadeus";
$a[0][1] = "Jeanny";
$a[1][0] = "Vienna Calling";
$a[1][1] = "Satellite to Satellite";

This matrix can easily be sorted by using the array_multisort command:

array_multisort($a[0], SORT_ASC, SORT_STRING,
    $a[1], SORT_ASC, SORT_STRING);

Both columns are sorted in ascending order. If you execute the script now, you will receive a sorted list:

Falco's masterpieces:
key:0 - subkey: 0 - value: Jeanny
key:0 - subkey: 1 - value: Rock me Amadeus
key:1 - subkey: 0 - value: Satellite to Satellite
key:1 - subkey: 1 - value: Vienna Calling

If you hadn't changed the data structure, you'd run into trouble because the size of the arrays would be inconsistent:

Warning: Array sizes are inconsistent in /var/www/html/test/hello.php on line 8

Array_multisort accepts two flags for influencing the way data is sorted. PHP supports two sorting order flags:

In addition, three sorting type flags are provided:

As you can see, array_multisort is a powerful and flexible function. However, it has to be used with care to make sure that the result of a sort process contains exactly the desired data.

You have already seen that a multidimensional array consists of many arrays that have one dimension less than the parent array. Knowing this will allow you to perform all operations you want to perform. Especially when working with multidimensional stacks, it is important to know what happens inside PHP and how data is stored by the interpreter.

3.4 Building Functions

Functions are the key to reusability. You have already learned to call PHP's built-in functions in this chapter but up to now you have not implemented your own functions. In this section you will learn to build your own PHP functions.

3.4.1 Simple Functions

Let's start with a simple example: Gauss's Formula for the sum of integers.

Johann Carl Friedrich Gauss was born on April 30, 1777, in Brunswick, Germany. At the age of seven, Carl Friedrich Gauss started elementary school, and his potential was noticed almost immediately. His teacher, Büttner, and his assistant, Martin Bartels, were amazed when Gauss summed the integers from 1 to 100 instantly by spotting that the sum was 50 pairs of numbers each pair summing to 101. Gauss's Formula for the sum of integers was born.

<?php
    $result = gauss(4);
    echo "Sum from 1 to 4: $result<br>\n";
 
# function for calculating the sum from 1 to $upper
function gauss($upper)
{
    if   (is_int($upper) && ($upper > 0))
    {
        return($upper*($upper+1)/2);
    }
}
?>

In the first line you can see that the function Gauss is called. One parameter has to be passed to the function. This parameter will define the upper limit for the sum you want to compute.

If the parameter passed to the function is an integer value and if it is higher than zero, the result is computed and returned to the main function. The result is passed to the main function by using the return command.

In this case 10 will be returned and displayed on the screen:

Sum from 1 to 4: 10

Functions can also be called with more than just one parameter. The next example shows a slightly adapted version of the function you have seen before. With the help of this function it is possible to compute the sum of integer values from a starting value to an upper value (the starting value is not included in the sum):

<?php
    $lower = 4;
    $upper = 10;

    $result = gauss($lower, $upper);
    echo "Result: $result<br>\n";

function gauss($lower, $upper)
    {
        if    ($upper >= $lower && $lower >= 0)
        {
            return ($upper*($upper+1)/2) - ($lower*($lower+1)/2);
        }
    }
?>

If you execute the script, the result will be displayed on the screen:

Result: 45

3.4.2 Passing Arrays to a Function

Sometimes it is necessary to pass entire arrays to a function. PHP does not support function overloading, but with the help of arrays it is possible to build simple workarounds.

The target of the next example is to compute the geometric mean of an array of values:

<?php
    $values = array(4, 3, 19, 23, 15);

    $result = geomean($values);
    echo "Result: $result<br>\n";

function geomean($invalues)
{
    foreach ($invalues as $val)
    {
        $sum += $val*$val;
    }
    return sqrt($val);
}
?>

First, an array containing various values is created. In the next step the function called geomean is called and the array is passed to it. Geomean computes the sum of all values to a power of 2 in the array. After that the square root is computed and returned to the main function. The result will be displayed on the screen:

Result: 3.8729833462074

3.4.3 Functions Returning More Than One Value

Up to now, you have dealt with functions returning just one value. However, it is possible for one function to return many values.

Let's have a look at the next example:

<?php
    $values = array(4, 3, 19, 23, 15);

    $result = compute($values);
    foreach ($result as $val)
    {
        echo "val: $val<br>\n";
    }

function compute($invalues)
{
    $result = array();
    $sum = 1;
    foreach ($invalues as $val)
    {
        $sum += $val*$sum;
        array_push($result, $sum);
    }
    return $result;
}
?>

First, an array is generated and passed to the function called compute, which performs some simple operations and returns an array of values.

The output is displayed on the screen:

val: 5
val: 20
val: 400
val: 9600
val: 153600

As you can see, it makes no difference if you want to return an ordinary variable or an array of values—the syntax is the same.

3.5 Exception Handling

Exception handling is a core feature of almost any programming language. Exception handling is not only necessary to detect errors but also for flow control. PHP provides a powerful exception-handling model that can easily be used by programmers. To show you how exception handling can be done, we have included a simple example:

<?php
    $a = "a string";
    if    (sqrt($a))
    {
        echo "Result: $b";
    }
    else
    {
        echo "The operation cannot be performed";
    }
?>

First, a string is defined. Then the script tries to compute the square root of the string, which is not possible. Therefore the condition evaluated by the if statement is not true and the else branch is entered.

If something happens that is not allowed in the script, it is necessary to quit the execution of a program. This can easily be done with the help of the die function:

<?php
    $a = 3;
    if    ($a < 5)
    {
        echo '$a is lower than 5';
        exit;
    }
    echo "This won't be executed";
?>

As you can see, $a is lower than 5, so the if condition is true and the script quits:

$a is lower than 5

The output of the echo command at the end of the script won't be displayed any more.

exit is not the only function provided by PHP to exit a script. If a message has to be displayed before exiting a script, die can be used instead of exit.

<?php
    $a = 3;
    array_push($a, 4) or
        die ('$a is not an array');

    echo "This won't be executed";
?>

A PHP error message is displayed on the screen. In addition, the message that has been passed to die is displayed as well:

Warning: First argument to array_push() needs to be an array in 
/var/www/html/index.php on line 3
$a is not an array

For real-world applications the error message generated by PHP is not suitable because it makes the user think that an error in the application has occurred. To make sure that no error is displayed to PHP, you can use @ to suppress the error:

<?php
    $a = 3;
    @array_push($a, 4) or
        die ('$a is not an array');

    echo "This won't be executed";
?>

If you execute the script, you will see that no PHP error is displayed:

$a is not an array

As you can see, PHP provides a flexible exception-handling system that can easily be used to catch almost all errors occurring during the execution of a script.

3.6 Working with Files

Workingwith files is easy in PHP. Files need not be located on the local machine to be accessible. It is also possible to work with remote files. In this section you learn to work with local and remote files efficiently.

3.6.1 Performing Basic Operations with Local Files

Working with files is an important issue for every programming language. The same applies to PHP. Functions for accessing the filesystem allow the user to build highly sophisticated applications. With the help of files it is possible to store information about what's going on in your application, or you can access external data sources. Nowadays a lot of information is stored in databases, but files are still a fundamental component of every applications. This section guides you through PHP's functions related to files and filesystems.

The first thing you have to know about files is how to open and close them:

<?php
    $handle = @fopen("data.file", "r") or 
        die ("cannot open file");
    echo 'File has successfully been opened<br>';
    fclose($handle);
?>

In this example fopen and fclose are used. These functions are available in many programming languages and have been borrowed from C.

In the script a file called data.file is opened for reading. This is done with the fopen function. The first parameter defines the name of the file that has to be opened. The second parameter tells PHP in which mode the file has to be opened. The following modes are supported by PHP:

Closing the file again is done by using fclose. Let's have a look at the content of the file the script has processed:

Hans::Vienna::Database Developer
Epi::Vienna::Consultant
Kuli::Vienna::Sales Manager
Sunny::Murau::Student

The file consists of four lines. Let's see what you can find out about the file using a Unix command:

[hs@athlon test]$ ls -l data.file
-rw-r--r--  1 hs    cybertec   107 Oct 21 13:21 data.file

The file is 107 bytes long and belongs to user hs in group cybertec.

Sometimes it is necessary to find out even more about a file. Therefore PHP provides a command called stat:

<?php
    $fileinfo = stat("data.file") or
        die ("cannot find information about file"); 

    echo "device: $fileinfo[0]<br>\n";
    echo "inode: $fileinfo[1]<br>\n";
    echo "inode protection mode: $fileinfo[2]<br>\n";
    echo "number of links: $fileinfo[3]<br>\n";
    echo "user id of owner: $fileinfo[4]<br>\n";
    echo "group id of owner: $fileinfo[5]<br>\n";
    echo "device type if inode device: $fileinfo[6]<br>\n";
    echo "size in bytes: $fileinfo[7]<br>\n";
    echo "time of last access: $fileinfo[8]<br>\n";
    echo "time of last modification: $fileinfo[9]<br>\n";
    echo "time of last change: $fileinfo[10]<br>\n";
    echo "blocksize for filesystem I/O: $fileinfo[11]<br>\n";
    echo "number of block allocated: $fileinfo[12]<br>\n";
?>

If you execute the script, a lot of information will be displayed on the screen:

device: 773
inode: 470215
inode protection mode: 33188
number of links: 1
user id of owner: 500
group id of owner: 500
device type if inode device: 2817
size in bytes: 107
time of last access: 1003663763
time of last modification: 1003663300
time of last change: 1003663300
blocksize for filesystem I/O: 4096
number of block allocated: 8

The output displayed by stat contains the same information that is also returned by the C function PHP's stat function is based on. To show you that PHP's functions for working with filesystems are based on C, we have included the structure returned by C's stat function:

struct stat {
    dev_t     st_dev;   /* device */
    ino_t     st_ino;   /* inode */
    mode_t    st_mode;   /* protection */
    nlink_t    st_nlink;  /* number of hard links */
    uid_t     st_uid;   /* user ID of owner */
    gid_t     st_gid;   /* group ID of owner */
    dev_t     st_rdev;   /* device type (if inode device) */
    off_t     st_size;   /* total size, in bytes */
    unsigned long st_blksize; /* blocksize for filesystem I/O */
    unsigned long st_blocks;  /* number of blocks allocated */
    time_t    st_atime;  /* time of last access */
    time_t    st_mtime;  /* time of last modification */
    time_t    st_ctime;  /* time of last change */
};

As you can see, the content of the result generated by PHP is nearly equal to the result generated by C. This shows clearly that PHP and C are strongly related. Knowing this will make it easy for you to understand the behavior and the functions of the PHP interpreter.

Up to now, you have learned to open and close files. You have also seen how to find out information about a file, but you haven't read and written data yet. Let's start with an example where you can see how data can be read from a file:

<?php
    $file = "data.file";
 
    $handle = fopen($file, "r") or
        die ("cannot open file");
    $fileinfo = stat($file);
 
    $data = fgets($handle, $fileinfo[7]);
    echo "data using fgets: <br>$data<br><br>";
 
    $data = fread($handle, $fileinfo[7]);
    echo "data using fread: <br>$data<br><br>";
 
    rewind($handle);
    echo "Pointer is at position: ".ftell($handle)."<br>";
 
    fseek($handle, 20);
    echo "Pointer is at position: ".ftell($handle);
 
    fclose($handle);
?>

First, a file is opened and information about that file is retrieved by using stat. $fileinfo[7] contains the size of the file. Although you have passed the content of $fileinfo[7] to fgets, only the first line will be read because fgets interprets newline characters. After reading the first line, the pointer is set to the beginning of the second line. Then fread is used. This time the rest of the file will be read and displayed on the screen because fread does not take care of newline characters. After reading all data, the file pointer is at the end of the file. To perform further reads, it is necessary to set it to a different position. Therefore rewind is used to set the pointer to the first position in the file. After that fseek sets the pointer to the 20th position in the file. Fseek and rewind are two essential functions when working with files because you can use them to go to any position within the file you are working with. Let's have a look at the output of the script:

data using fgets:
Hans::Vienna::Database Developer

data using fread:
Epi::Vienna::Consultant Kuli::Vienna::Sales Manager Sunny::Murau::Student

Pointer is at position: 0
Pointer is at position: 20

As you can see, the result is displayed on the screen correctly.

The next example shows how data can be written to a file:

<?php
    $file = "data.file2";
 
    $handle = fopen($file, "w") or
        die ("cannot open file");
    fputs($handle, "Hello World");
    fclose($handle);
?>

$handle contains the pointer of the new file created by fopen. Then fputs is calledand a string is written to the file before closing it.

Up to now, you have only used rudimentary I/O functions. In some cases, it is more comfortable to read an entire file into an array:

<?php
    $file = "data.file";
 
    $data = file($file);
 
    echo '<table border="1"><tr>';
    echo "<th>name</th><th>location</th><th>profession</th></tr>";
 
    foreach     ($data as $line)
    {
        $val = explode("::", $line);
        echo "<tr><td>$val[0]</td><td>$val[1]</td><td>
            $val[2]</td></tr>";
    }
    echo "</table>";
?>

Reading a file into an array can be done with a function called file. To use file, it is not necessary to open the file first with fopen becausethis done implicitly by file. An array is returned. In the example the array is processed line by line and the string in the line is split after every ::. That way an array called $val is initialized every time the loop is processed and a table can be generated, which you can see in Figure 3.2.

Figure 3.2Figure 3.2 A simple table.

If you want to display the content of the file on the screen without processing the data beforehand, you can use the readfile function instead. readfile(filename) opens a file and displays the content on the screen directly. This is very useful when the file already contains HTML code.

3.6.2 Performing Basic Operations with Remote Files

In the previous section you have seen how local files can be treated with PHP. Remote files can be processed in a similar way.

Here is the example you have just seen, but this time the data comes from a remote host:

<?php
    $file = "http://212.186.25.254:/test/data.file";
 
    $data = file($file);
 
    echo '<table border="1"><tr>';
    echo "<th>name</th><th>location</th><th>profession</th></tr>";
 
    foreach     ($data as $line)
    {
        $val = explode("::", $line);
        echo "<tr><td>$val[0]</td><td>$val[1]</td><td>
            $val[2]</td></tr>";
    }
    echo "</table>";
?>

As you can see, the only change that has to be made is that the position of the file is now defined by an URL. If you have the permissions to read that file, it can be processed like any other file.

Every time the script is processed, however, the Web server will add one line to the logfile:

212.186.25.254 - - [21/Oct/2001:16:30:02 +0200] "GET /test/data.file HTTP/1.0"
 200 107 "-" "PHP/4.0.4pl1"

As we have already mentioned, working with remote files works just the same way as with local files. However, some important things have to be taken into consideration:

<?php
    $file = "http://212.186.25.254:/test/data.file";
    $handle = fopen($file, "a+") or
        die ("cannot open $file");
    fputs($handle, "Pat::Indianapolis::Lawyer") or
        die ("cannot write to file");
    fclose($handle) or
        die ("cannot close file");
    echo "it works";
?>

Most people expect that the script will append data to the remote file, but this does not happen:

[hs@athlon test]$ cat data.file
Hans::Vienna::Database Developer
Epi::Vienna::Consultant
Kuli::Vienna::Sales Manager
Sunny::Murau::Student

Nothing has been appended to the remote file, although the output of the script is "it works" and no error has occurred while executing. This has to be taken into consideration when working with remote files; otherwise, you might wonder why your application returns no errors and produces no output.

3.6.3 Additional Filesystem Functions

As you have already seen, PHP offers functions for working with local and remote files. Up to now, you have seen how to perform all basic operations. In this section you will see that PHP provides a lot more functions than you have already seen:

As you can see, PHP provides an endless list of built-in functions. Most functions work with all common filesystems. Especially on Unix systems, PHP shows its tremendous power because some functions can only be used on Unix.

3.7 Variables and Scope

Variables cannot be "seen" in the entire application. This is a very important issue because otherwise programmers would easily run into trouble. Especially when building huge applications, it is important to know where which variables can be seen and used.

Let's start with a simple example:

<?php
    $a = "Hello World";
    echo "main: $a<br>\n";
    display_data();
 
function display_data()
{
    echo "display data: $a<br>\n";
}
?>

First, $a is initialized and displayed on the screen. Then display_data is called, which tries to display $a again:

main: Hello World
display data: 

As you can see, display_data displays nothing because $a cannot be seen by the function. $a has been initialized in the main function and therefore it is not visible for functions called by the main function.

However, if you have to access $a in display_data, it has to be declared as global:

<?php
    $a = "Hello World";
    echo "main: $a<br>\n";
    display_data();
    echo "main: $a<br>\n";
 
function display_data()
{
    global $a;
    echo "display data: $a<br>\n";
    $a = "Hello Frank";
}
?>

With the help of the keyword global, it is possible to read and modify any global variable:

main: Hello World
display data: Hello World
main: Hello Frank

As you can see, the content of $a can be modified by display_data.

Another way to access $a is to use an array called $GLOBALS:

<?php
    include("inc/vars.php");
 
    echo "main: $a<br>\n";
    display_data();
 
function display_data()
{
    echo "display data:".$GLOBALS["a"];
}
?>

With the help of $GLOBALS, it is possible to access any variable that has been defined globally. When executing the script, the output will be displayed on the screen:

main: Hello World
display data:Hello World

Another important thing, especially when dealing with huge projects, is to include variables using a command called include. With the help of include, files containing functions and variables can be added to a PHP script and will be visible for the interpreter. In the next example you will see a file called vars.php, which will be included in the script.php. Let's get to vars.php first:

<?php
    # Defining a string
    $a = "Hello World";
?>

As you can see, the file contains only the definition of $a. In script.php vars.php is included, so $a can be accessed as if it were defined in script.php.

<?php
    include("inc/vars.php");
 
    echo "main: $a<br>\n";
    display_data();
 
function display_data()
{
    global $a;
    echo "display data: $a<br>\n";
}
?>

It is recommended to put files that contain only definitions of variables in a separate directory so that these files cannot be mixed up with files containing other source code.

When executing the script, you will see that the result will be the same as in the previous example:

main: Hello World
display data: Hello World

Including one file is simple, but what happens when the file included in script.php contains included files? Let's have a look at the code of script.php.

<?php
    include ("inc/vars.php");
 
    echo "$a<br>";
    echo "$b";
?>

This time vars.php does not contain the definition of the variables but includes two files containing the definition of $a and $b.

<?php
    include ("inc/base_a.php");
    include ("inc/base_b.php");
?>

$a is defined in base_a.php:

<?php
    $a = "Hello World";
?>

$b is defined in base_b.php:

<?php
    $b = "Greetings from Austria";
?>

What happens when script.php is executed?

Hello World
Greetings from Austria

Both variables will be displayed. All variables included in vars.php are visible in script.php as well.

Static variables, like many other components of PHP, have been borrowed from C/C++. Static variables can be used to build functions that are able to remember values. Especially for recursions, this is an important feature. To show you what you can do with static variables, we have included a brief example:

<?php
    for   ($i=1; $i<=6; $i++)
    {
        echo display_data($i)."<br>\n";
    }
 
function display_data($i)
{
    static $var;
    $var .= "$i";
    return $var;
}
?>

A loop makes sure that display_data is called six times. $var is defined as a static variable, which means that it will remember the value it had the last time display_data was called. Every time the function is called, the current value of $i is added to $var.

If you execute the script, you will see that the length of $var grows every time display_data is processed:

1
12
123
1234
12345
123456

Static variables have disadvantages as well as advantages. Bugs caused by static variables are sometimes difficult to find, and it can be very painful to look for errors that can only be found by extensive debugging.

3.8 Building Packages

Even when writing very small applications, it is recommended to block functions used for certain parts of the applications in separate files. When writing an application used for displaying stock charts, for instance, it can be useful to have separate libraries for functions related to retrieving data and functions for displaying the data. This will help you to reuse code for other applications. In addition, your functions are more consistent because not every application has its own implementation of a block of functions.

Writing reusable code is the first step to writing reliable code. The more often a piece of code is used, the more mature it will be because more testing has been done.

Another important issue is that packages must be independent from the programs using them. In other words, don't access global variables of the main program from a library, or your code might not be reusable any more and the programmer using a library has to know what is going on inside your library. A library will be a black box for those people using it. According to the KISS principle (Keep It Small and Simple) of Unix systems, this is an essential point because other things will be far too complicated.

Try to build small, easy-to-understand, and independent modules with a fixed interface and make sure that the user of a library does not have to know what is going on inside your library.

The next code fragment shows a small example. The target is to write a module that swaps the content of two variables. Let's have a look at the main program first:

<?php
    include ("lib/transform_data.php");
 
    $a = 23;
    $b = 37;
 
    swapdata_ref($a, $b);
    echo "a: $a<br>";
    echo "b: $b";
?>

At the beginning of the script a library is included. In the next step two variables are defined. These are the variables you want to swap. Then swapdata_ref is called and the values are passed to the function. After that the variables are displayed so that you can see that they have really been swapped. Up to now, swapdata_ref is a black box, and it is not necessary to know how variables can be swapped because the interface is the function is clearly defined. However, let's have a look at what the function does internally:

<?php
 
function swapdata_ref(&$x, &$y)
{
    $c = $x;
    $x = $y;
    $y = $c;
}
 
?>

A reference is passed to the function and the values are swapped using a temporary variable called $c. As you can see, the function has no return values. Because a reference is passed to the swapdata_ref, the function is able to access the variables directly (using the internal addresses of the values) without having to access the variables using global variables. This way of solving the problem is very comfortable because swapdata_ref does not have to know how the variables in the function calling the swap function are called—the addresses of the values that have to be processed are assigned to their new names when the function is called.

When executing the script, you will see that the variables have been swapped:

a: 37
b: 23

Like many other things, references are borrowed from C and are a powerful feature because it would be far too uncomfortable to work with global variables or passing huge amounts of data to a function.

3.9 Working with Forms

Up to now, you have seen how to write simple PHP applications. However, for building interactive Web sites it is necessary to allow the user to insert data into so-called forms. The content of such forms can be transmitted to the server and a PHP script can react based on the data sent to it. Interacting with a Web server can be done with two methods called GET and POST.

3.9.1 GET and POST

The methods GET and POST are described in RFC2068, which is longer than 160 pages. In this section you learn about the main ideas behind GET and POST, and you learn to use these two methods efficiently.

3.9.1.1 GET

GET is the standard request method for retrieving data from a Web server. When calling a Web site, GET is used to get the document you have selected. Normally calls like that don't have side effects, and that is what GET should be used for. Browsers assume that GET has no side effects and if the page is not in the browser's cache any more, the page will be retrieved again. However, if the original request was via POST, the user would receive a message that the document is no longer in the cache (in section "Building Forms" in this chapter, you will learn to get around this problem).

3.9.1.2 POST

POST is the standard method for submitting data stored in a form to Web server. In the case of POST, the request always contains a body where the information related to the request is stored. This information is coded like a query string. Normally Web developers use POST even when no data on the server is modified.

3.9.2 Building Forms

After you have seen which methods can be used to retrieve data from a Web server, you have a look at a simple form that can be used to send text to a PHP file:

<html>
<body>
    A Simple Form
    <br><br>
    <form action="reaction.php" method="POST">
        <input type="text" name="field_1" size="10"><br><br>
        <input type="submit" name="submitbutton">
    </form>
</body>
</html>

In line number 5 a form is defined. When the user clicks on the Submit button, the data will be sent to reaction.php. The form consists of two components. The first component is a text field called field_1. The second component is the button to submit the form. The end of the form is marked by </form>.

Let's start the script and see what the browser displays (see Figure 3.3).

Figure 3.3Figure 3.3 A simple form.

If you click the button, reaction.php will be started:

<?php
    if   ($field_1)
    {
        echo "field_1: $field_1";
    }
    else
    {
        echo "nothing has been passed to this script";
    }
?>

The first thing done by the script is to see if $field_1 is defined. If the user has inserted data into the form, the variable will be defined in PHP automatically. In contrast to Perl, PHP programmers do not have to extract the variables from the query string themselves because everything is done by PHP.

If $field_1 is defined, the content of the variable will be displayed on the screen.

As you can see, retrieving data from a form is an easy task. In the next step you will see how more complex forms can be built with the help of HTML:

<html>
<body>
    A more complex form
    <br><br>
    <form action="reaction.php" method="POST">
        <input type="text" name="field_1" size="10"><br><hr>
 
        <input type="checkbox" name="box_1">
            display time<br><hr>
 
        <input type="radio" name="myradio" value=1>Value 1<br>
        <input type="radio" name="myradio" value=2>Value 2<br>
        <input type="radio" name="myradio" value=2>Value 3<br><hr>
 
        <input type="password" name="passwd">
            Enter passwords here<br><hr>
 
        <input type="file" name="filename">
            enter the filename<br><hr>
 
        <input type="reset" name="resetbutton">
        <input type="submit" name="submitbutton">
    </form>
</body>
</html>

The first component defined in the form is a text field again. The length of the field is set to 10. In addition to the size of the field, it would also be possible to define the maximum length of the text the user is allowed to insert. This can be done by using maxlength. After defining the text field, a check box is defined. The name is set to box_1. After that you can see how radio buttons can be added to a HTML document. In the example you can see that myradio consists of three components. Only one of those three components can be activated. Depending on which of the three buttons is checked, the appropriate value is sent to reaction.php. If you need fields for inserting passwords, password will be the right type for you. While typing, the user will only see asterisks, so nobody can grab the user's password.

To select a file on the user's hard disk, the type called file can be used. File will create a text box and a button you can click if you need a window where you can select the file using a graphical interface.

Finally, the Submit button is added to the screen. Figure 3.4 shows what comes out when you execute the script.

Figure 3.4Figure 3.4 A more complex form.

If you click on the Submit button, the data inserted into the form will be sent to reaction.php:

<?php
    echo "field_1: $field_1<br>";
    echo "myradio: $myradio<br>";
    echo "passwd: $passwd<br>";
    echo "filename: $filename<br>";
?>

The script displays the values on the screen:

field_1: 23
myradio: 2
passwd: a password
filename: /home/hs/boot.img

Keep in mind that the values in the listing show what you have inserted into the form. The gist of the example is that the information from every field in the HTML form will be stored in a variable after being submitted to a PHP file.

Sometimes it is necessary to give the user the opportunity to select more than just one value in a list. Therefore HTML offers a simple solution using select and option:

<html>
<body>
    Select:
    <br><br>
    <form action="reaction.php" method="POST">
        <select name="fruits[]" multiple size=4>
            <option value="Orange">Orange
            <option value="Banana">Banana
            <option value="Apple">Apple
            <option value="Pineapple">Pineapple
            <option value="Strawberry">Strawberry
            <option value="Cherry">Cherry
            <option value="Coconut">Coconut
        </select><br><br>
 
        <input type="submit" name="submitbutton">
    </form>
</body>
</html>

Now the user can choose some of the fruits presented in the list. Because more than one fruit can be selected, the data structure used by PHP must be an array. In our example this array is called fruits[]. After submitting the content of the form, the array will contain all values the user has selected. To display the content of the array, a simple function can be used:

<?php
    foreach ($fruits as $var)
    {
        echo "$var<br>";
    }
?>

The fruits will be listed one after the other.

3.9.3 Passing Parameters to a Script

In many cases it is useful to call a script and pass some parameters to it. Techniques like that are often needed for banners because the person who has paid for the banner wants to know where a click comes from. For that purpose, parameters are passed to a script that contains information on whose Web site contained the banner.

Let's have a look at a very simple script that does nothing except display two variables.

<?php
    echo "a: $a<br>\n";
    echo "b: $b\n";
?>

The target is to pass parameters to that script via an URL:

http://localhost/test/script.php?a=234&b=197

The script named script.php located in a directory named test on the local Web server is called with the parameter a=237 and b=197. The names of the script and the parameters are separated using a question mark (?). The list of parameters is separated using ampersands (&).

When executing script.php, the result will be displayed by the browser:

a: 234 
b: 197

You have already seen that question marks and ampersands are used as delimiters. What happens if you want to pass one of these signs to the script? Does the Web server get confused because it has to find out which symbols are used as delimiters of which ones are parts of a string? The answer is yes. All "special" characters have to be escaped so that the Web server can parse the URL easily. Luckily PHP provides a function called urlencode, which takes care of things like that. Let's write a small script that generates a list of URLs:

<?php
    echo "<html><body>\n";
 
    $messages[0] = "Pat and Shelley";
    $messages[1] = "Pat & Shelley";
    $messages[2] = "Pat & Shelley!";
    $messages[3] = "Are you sure?";
    $messages[4] = "Hans-Jürgen Schönig";
 
    foreach ($messages as $var)
    {
        echo '<a href="script.php?a='.urlencode($var).
            '"> '.$var."</a><br>\n";
    }
 
    echo '</body></html>';
?>

After displaying some HTML code, five strings are defined and assigned to an array called $messages. Each of the strings contains certain characters that have to be escaped by PHP.

In the next step, links are generated using urlencode. Let's call PHP from the command line and see what the HTML code generated by the script looks like:

[hs@athlon test]$ php genurl.php
X-Powered-By: PHP/4.0.4pl1
Content-type: text/html
 
<html><body>
<a href="script.php?a=Pat+and+Shelley"> Pat and Shelley</a><br>
<a href="script.php?a=Pat+%26+Shelley"> Pat & Shelley</a><br>
<a href="script.php?a=Pat+%26+Shelley%21"> Pat & Shelley!</a><br>
<a href="script.php?a=Are+you+sure%3F"> Are you sure?</a><br>
<a href="script.php?a=Hans-J%FCrgen+Sch%F6nig"> Hans-Jürgen Schönig</a><br>
</body></html>

As you can see, all characters have been escaped. When executing the script using a Web browser, the strings in the array are displayed as links:

Pat and Shelley
Pat & Shelley
Pat & Shelley!
Are you sure?
Hans-Jürgen Schönig

If you click on the first link, script.php will be called:

a: Pat and Shelley
b: 

The text is displayed on the screen. Because no parameters for $b have been passed to the script, the field is empty.

3.9.4 Working with Hidden Fields

Sometimes it is necessary to pass parameters to a script that should not be seen by the user. In HTML it is possible to use hidden fields. The difference between "ordinary" fields and hidden fields is that hidden fields are not displayed by the browser. Therefore parameters can easily be passed from one script to another without giving the user the opportunity to modify the information stored in a hidden field.

Let's assume that you want to write a script that displays the time the previous script has been created:

<?php
    $curtime = localtime();
    $timestr = strftime("%Y %b %d: %T %Z");
    echo "timestr: $timestr<br>\n";
 
    echo '
        <html>
        <body>
            Hello World
            <form action="reaction.php" method="POST">
            <input type="hidden" value="'.$timestr.
                '" name="gentime">
            <input type="submit" name="submitbutton">
        </form>
        </body>
        </html>
    ';
?>

The first script generates the current time and stores it in $timestr. Now a form is generated and the value $timestr is used as the default value of the field called gentime. The only two things that are displayed on the screen are the content of $timestr, Hello World, and a button to submit the information. Reaction.php is called when the user hits the button. Let's have a look at reaction.php:

<?php
    echo "gentime: $gentime";
?>

The content of $gentime is displayed on the screen:

gentime: 2001 Nov 01: 12:31:57 CET

The previous script has been generated at the time listed in the output of reaction.php. Sometimes it is useful to pass the time when the first HTML was generated to all files because this way it is possible to find out when a user has entered the page.

3.10 Debugging PHP

After you have learned to write simple PHP applications, it is time to verify that your applications work. Therefore debugging has to be done.

In PHP3 a debugger was included that was able to send data to a TCP port where it can easily be monitored with the help of a listener.

Unfortunately in PHP this debugger can only be used if you buy the ZEND IDE (http://www.zend.com/store/). Some other debuggers are available for PHP, but we do not cover these products in this book. However, in this section you learn to debug PHP programs using PHP onboard tools.

The easiest way to debug PHP code is to write a debugging function. Let's assume that you want to monitor the content of $i:

<?php
    include ("debug.php");
 
    for   ($i=1; $i <= 5; $i++)
    {
        echo "i: $i<br>\n";
        debug("\$i: $i");
    }
?>

Every time the loop is processed, you can call a function called debug, which can be found in debug.php.

Let's see how we implemented this function:

<?php
 
# Write debugging info to a logfile
function debug($var)
{
    setlocale("LC_TIME","en_US");
    $datum=strftime("[%d/%b/%Y:%T %Z]");
    $log_str="$datum -- $var\n";
    $fp=fopen("/tmp/debug.log","a+");
    if ($fp)
    {
        fwrite($fp,$log_str);
        fclose($fp);
    }
    else
    {
        echo"error";
        exit;
    }
}
?>

First, the way time is displayed is set to English style. In the next step the date is compiled and stored in $datum. $log_str will contain the complete string added to the logfile, which will be located in the /tmp directory.

With the help of fwrite, $log_str is added to the file before it is closed again.

After executing the script, you can find the debugging information in the logfile:

[27/Oct/2001:09:38:31 CEST] -- $i: 1
[27/Oct/2001:09:38:31 CEST] -- $i: 2
[27/Oct/2001:09:38:31 CEST] -- $i: 3
[27/Oct/2001:09:38:31 CEST] -- $i: 4
[27/Oct/2001:09:38:31 CEST] -- $i: 5

As you can see, the logfile is generated using the Apache style of logging. With the help of logfiles, it is an easy task to monitor your application and find out what has happened inside a program.

However, this information might not be enough for you. Especially when monitoring production environments in which many concurrent processes are running on the system, it is necessary to have some information about which process generated what kind of information. To compute this information, PHP offers some easy-to-use functions. getmypid retrieves the process ID of the current process and get_current_user finds out which user executes the script.

The information can be added to the logfile by modifying the line generating $log_str:

$log_str="$datum [".getmypid()."] ".get_current_user()." -- $var\n"; 

Now the logfile will contain the process ID and the name of the user executing the script:

[27/Oct/2001:10:06:11 CEST] [4661] hs -- $i: 1
[27/Oct/2001:10:06:11 CEST] [4661] hs -- $i: 2
[27/Oct/2001:10:06:11 CEST] [4661] hs -- $i: 3
[27/Oct/2001:10:06:11 CEST] [4661] hs -- $i: 4
[27/Oct/2001:10:06:11 CEST] [4661] hs -- $i: 5

With the help of this information, it is an easy task to distinguish the scripts running on the server.

In general it is hard to give rules for how debugging can be done best. In most cases, how to find bugs fast and reliably is a matter of personal preference. One thing can be said for sure: Don't hurry when looking for bugs.

3.11 Summary

PHP is a powerful and easy-to-use language. The main advantages of PHP are its flexibility and simplicity. Web applications can be written easily and fast. This makes PHP a good choice for prototyping and rapid application development.

800 East 96th Street, Indianapolis, Indiana 46240