Control Structures

You use control-structures to control the flow of execution through your program. If you didn’t have any of these control-structures, all your scripts would always do the same. So let’s get on with it.

The if-statement

We start with the if-statement which is the most basic control-structure. You use the if-statement to execute different parts of your script based on the truth-value of an expression. The expression could be something like $a > 5 which will be true when the variable $a has a numerical value greater than 5. When the expression is true the next part of the if-statement is executed. If the expression is false, then the optional else-part of the if-statement is executed. In a script it would look like this:

if ($a < 5) {
  $b = $a + 10;
} else {
  $b = $a * 2;
}

If the part between the parenthesis, (...), is true, then the statements between the first pair of curly braces, {...} is executed. Else the part in the curly brackets after the else keyword is executed. You don’t have to provide a else-part, and if you don’t then nothing will be executed if the test is false.

You can have all kinds of statement between the parenthesis and the curly braces. PHP is a language where almost every statement has a value, a value that can be used together with other values to build big expressions.

Take an assignment for example. The statement $b = $a actually has a value, namely the value of $a. This means that you can use this value in another assignment, like this:

$c = ($b = $a);

The assignment in the parenthesis has the value of $a which is then assigned to $c. You can actually drop the parenthesis; the result is the same: all three variables have the value of $a. This allows you to understand a statement like this:

/* Initialize counters: */
$i = $j = $k = $l = 0;

To compare the value of a variable up against other variables or numbers, you have a number of different comparison-operators:

  • ==: Is equal to,
  • !=: Is not equal to,
  • <: Is strictly less than,
  • <=: Is less than or equal to,
  • >: Is strictly greater than,
  • >=: Is greater than or equal to,
  • && (and): Both left and right arguments must be true,
  • ||, or: Left or right argument must be true (or both),
  • ^, xor: Exactly one of the left and right arguments must be true.
  • !: Negation, changes true to false and false to true.

Using these operators you can construct every Boolean expression you’ll ever need. Take for example the following if-statement:

if (($x == 0 && $y != 0) || ($x != 0 && $y == 0))
  // Exactly one of $x and $y is zero.
}

This if-statement determines if exactly one of $x and $y is zero. We will return to this test below.

If the value of a boolean expression is determined, then the execution is stopped immediately. The logic is said to short-cut. This means that

if (true || $x / 0 == 42) { ... }

wont trigger an error because of the division by zero, because the execution of the condition in the if-statement was terminated when it was discovered that it must be true. You will sometimes see this short-cut logic used as in the following statement:

mysql_connect() or die('Could not connect to the database!');

The function mysql_connect() tries to make a connection to a MySQL database. It returns true if it was able to make a connection. PHP evaluates the line as a Boolean expression. That means that it starts by executing mysql_connect(). If that returns true, then PHP skips the next statement, because we used or. The second statement makes PHP stop with an error message, if the first statement fails. As you can see, you can make it as complicated as you want.

You can use integers instead of booleans in your tests — PHP will treat 0 as false and any other number as true. That means that the test ($x == 0 && $y != 0) || ($x != 0 && $y == 0) given above can be expressed as

if (!$x && $y) || ($x && !$y) { ... }

which should be read as “not $x and $y, or $x and not $y“. This is a more clear way to indicate that exactly one of $x or $y must be true. Using the ^ operator for exclusive-or, you can express the same thing in a very concise way:

if ($x ^ $y) { ... }

The for-loop

The for-loop is useful when you need to have the same task repeated a number of times. The for-loop works by first initializing a variable, then performing a test, and then — if the test is true — executing some code. After that code has been executed, additional code is run to increment the variable and then execute the main code again. An example will probably help:

for ($i = 0; $i < 10; $i++) {
  echo $i;
}

“Hmm, now he introduced several new things again” you might think. And you’re perfectly right. First, let’s have a look at the for-loop.

It first assigns a starting-value of 0 to $i, then it checks to see if $i is smaller than 10, and, if so, the echo-statement is executed. At the end of an iteration, (one pass of the loop) the $i++ statement is executed.

This last statement is a shorthand of $i = $i + 1;. It simply increments the variable $i by 1. Similarly, you could write $n--; that would decrement the variable $n by 1.

The main code is executed while $i is less than 10, so our little for-loop simply prints the numbers from 0 to 9 into our webpage.

The while-loop

The while-loop is very similar to the for-loop. It works like this:

while (something is true) {
  some statements
}

It is used when you don’t know in advance how many iterations you’ll need. If you look close, then you’ll see that each for-loop can be made into a while-loop and that each while-loop can be made into a for-loop. This is because a for-loop like this (where a, b, c, and d are statements):

for (a; b; c) {
  d;
}

works completely like this while-loop:

a;
while (b) {
  d;
  c;
}

You’ll often see a while-loop being used to run though an array like this:

while (list($key, $val) = each($array)) {
  echo "<p>$key => $val\n";
}

The condition in the while-loop uses several functions and an assignment. Each time the function each() is called, it returns an array with the key and value from $array. When there are no elements left in $array, each() returns false. Remember that an assignment has a value — the value which is being assigned, so when each() returns false, it the whole condition false and the while-loop stops.

The list() function can be used on the left side of an assignment to extract values from an array. You can use list() like this, although it would be much easier to assign the variables one at a time:

// $a == 1, $b == 2, $c == 3, $d == 4:
list($a, $b, $c, $d) = array(1, 2, 3, 4);

So the condition in the while-loop prepares $key and $val for the body of the loop. When all key-value pairs have been examined, the loop terminates because each() return false, which then becomes the value of the assignment, and therefore the value of the condition.

After you’ve run through the array like this, each() will return false if you use it on the same array. You’ll have to call reset($array) to make each() start from the beginning again.

Here is an example with reset() and each() that will build a table that shows the keys and values of an array:

// Some data for our table
$array = array('Foo' => 42,
               'Bar' => 3.14,
               'Baz' => 2.71);

// Start the table, note the escaping of the double-quotes
echo "<table border=\"1\">\n";
// Print the first row with headers
echo "<tr>\n";
echo "  <th>Key</th>\n";
echo "  <th>Value</th>\n";
echo "</tr>\n";

// Ensure that the each() function starts from the start:
reset($array);
// Now get the next row using each()
while (list($key, $value) = each($array)) {
  // Print a single row
  echo "<tr>\n";
  echo "  <td>$key</td>\n";
  echo "  <td>$value</td>\n";
  echo "</tr>\n";
}
// End the table
echo "</table>\n";

This code will produce a table like this one:

Key Value
Foo 42
Bar 3.14
Baz 2.71

The important thing for you to notice in the above code is the way HTML tables can be built up in PHP. Tables in HTML start with the opening tag, and then comes any number of rows, each row consists of any number of cells. Finally you close the table again.

So when building HTML tables using PHP, remember that they always start in the upper left-hand corner (the cell that says “Key” in this example) and then continue to the right along the same row. When the row is done, the next row follows in the same way, left-to-right, until you finally end up in the lower right-hand corner (that’s the cell that says “2.71″ here).

The foreach() Construct

The foreach() construct is designed to do the above with less code, and works like this:

foreach($array as $key => $value) {
   // Echo the table exactly as above in the body of the while-loop.
}

The => syntax (not to be confused with <=, the less-than operator) used with the foreach loop is not an operator as such, but a fixed syntax used here and there in PHP in relation to arrays.

Read it as “points-to” or something similar, it indicates that the variable $key points to $value. You can choose the variable names freely, but you should try to make them descriptive (as always when choosing variable names).

So at each consequetive execution of the body in the foreach loop the variable $key will hold the name of the current key, and $value will hold the corresponding value, that is, $array[$key].

You have already learned to use some of the builtin functions in PHP. But the fun doesn’t stop there — learn how to define your own functions.

11 Comments

  1. Jim Davis:

    I tried the above table code as it was but it wasn’t until I changed it to:

    echo “\n”;

    that it actually showed the table. Is that normal? I tried it the other way but it just showed the numbers but no table I had to add the border= to get the table to show.

  2. Martin Geisler:

    The table code produces the following HTML code, no more, no less:

    <table>
    <tr>
      <th>Key</th>
      <th>Value</th>
    </tr>
    <tr>
      <td>Foo</td>
      <td>42</td>
    </tr>
    <tr>
      <td>Bar</td>
      <td>3.14</td>
    </tr>
    <tr>
      <td>Baz</td>
      <td>2.71</td>
    </tr>
    </table>
    

    This HTML code should produce a table similar to the one described above but with no border — adding border="1" to the <table> tag will give you a border. This has actually nothing with PHP to do, it is a matter of HTML. (Not that this makes the mismatch between the code and the example better — I’ll update the code now.)

  3. Elias_Maluco:

    Sorry, but could you explain what the “=>” operator does? You just started using it, but I cant find where do you explained anything about it.

  4. Elias_Maluco:

    Also, \n is simply not working here. Im using Apache 2.0.54 and PHP 5.0.4 in Windows XP. When a put \n in a string, it doenst get echoed, but it doesnt break the line neither. So, Ive been using instead.

    So, if I try:
    echo “Two\nlines”; I get simply “Two lines” printed on the page.
    I have to write “Two<br>lines”; to achieve the same effect;

  5. Martin Geisler:

    (I’ve edited your comment to include the <br> that got deleted — HTML tags are not allowed comments, but I had expected them to be escaped…)

    As for your question: when looking for the “\n” are you looking at the source of your document? It is only there you’ll see the “\n”. All whitespace are treated like a single space in HTML, so your newlines, tabs, carrige returns, and a bit more are all turned into a single space when displayed by the browser.

    The exception to this is content within <pre> tags. There your formatting is preserved. Was that your problem?

  6. Martin Geisler:

    I’ve tried to explain the => syntax in the text, please tell me if that helps or if I could explain it better.

  7. Elias_Maluco:

    Yes, thank you very much. And I found where you explained about the =>, I just have the bad habbit of jumping sentences while I read. Sorry about that.

  8. Andrea:

    I like it and the background and colors make it easy to readn

  9. mickeystinge:

    In your example of boolean operations in the If structure section…
    if (($x == 0 && $y != 0) || ($x != 0 && $y == 0)) {
    // At least one of $x and $y is zero.
    }
    …surely this is not ‘// At least one of $x and $y is zero’ but true if only one of x or y is zero, but not both ie an exclusive OR function. You would need to code…
    if (($x == 0 && $y != 0) || ($x != 0 && $y == 0) || ($x == 0 && $y == 0))
    …or simply…
    if (($x ==0) || ($y == 0))
    …am I right?

  10. Martin Geisler:

    9: Yeah, you’re right! Thanks for pointing it out, I’ll update the text.

  11. Patrick Elward:

    Nice tutorial. You may want to update the table example slightly.
    It didn’t render properly for me, so I changed quotes from double to single.

    In your example above, I changed

    echo “

    <

    table border=”1″>n”;

    to

    echo “

    <

    table border=’1′>n”;

    and the PHP worked. Just wanted to let you know. cheers!

Leave a comment