Programming PHPProgramming PHPSearch this book

2.5. Flow-Control Statements

PHP supports a number of traditional programming constructs for controlling the flow of execution of a program.

Conditional statements, such as if/else and switch, allow a program to execute different pieces of code, or none at all, depending on some condition. Loops, such as while and for, support the repeated execution of particular code.

2.5.1. if

The if statement checks the truthfulness of an expression and, if the expression is true, evaluates a statement. An if statement looks like:

if (expression) 
  statement

To specify an alternative statement to execute when the expression is false, use the else keyword:

if (expression) 
  statement 
else 
  statement

For example:

if ($user_validated)
  echo "Welcome!";
else
  echo "Access Forbidden!";

To include more than one statement in an if statement, use a block —a curly brace-enclosed set of statements:

if ($user_validated) {
  echo 'Welcome!";
  $greeted = 1;
} else {
  echo "Access Forbidden!";
  exit;
}

PHP provides another syntax for blocks in tests and loops. Instead of enclosing the block of statements in curly braces, end the if line with a colon (:) and use a specific keyword to end the block (endif, in this case). For example:

if ($user_validated) :
  echo "Welcome!";
  $greeted = 1;
else :
  echo "Access Forbidden!";
  exit;
endif;

Other statements described in this chapter also have similar alternate style syntax (and ending keywords); they can be useful if you have large blocks of HTML inside your statements. For example:

<?if($user_validated):?>
  <table>
    <tr>
      <td>First Name:</td><td>Sophia</td>
    </tr>
    <tr>
      <td>Last Name:</td><td>Lee</td>
    </tr>
  </table>
<?else:?>
  Please log in.
<?endif?>

Because if is a statement, you can chain them:

if ($good)
  print('Dandy!');
else
  if ($error)
    print('Oh, no!');
  else
    print("I'm ambivalent...");

Such chains of if statements are common enough that PHP provides an easier syntax: the elseif statement. For example, the previous code can be rewritten as:

if ($good)
  print('Dandy!');
elseif ($error)
  print('Oh, no!');
else
  print("I'm ambivalent...");

The ternary conditional operator (?:) can be used to shorten simple true/false tests. Take a common situation such as checking to see if a given variable is true and printing something if it is. With a normal if/else statement, it looks like this:

<td><? if($active) echo 'yes'; else echo 'no'; ?></td>

With the ternary conditional operator, it looks like this:

<? echo '<td>'.($active ? 'yes':'no').'</td>' ?>

Compare the syntax of the two:

if (expression) true_statement else false_statement
(expression) ? true_expression : false_expression

The main difference here is that the conditional operator is not a statement at all. This means that it is used on expressions, and the result of a complete ternary expression is itself an expression. In the previous example, the echo statement is inside the if condition, while when used with the ternary operator, it precedes the expression.

2.5.2. switch

It often is the case that the value of a single variable may determine one of a number of different choices (e.g., the variable holds the username and you want to do something different for each user). The switch statement is designed for just this situation.

A switch statement is given an expression and compares its value to all cases in the switch; all statements in a matching case are executed, up to the first break keyword it finds. If none match, and a default is given, all statements following the default keyword are executed, up to the first break keyword encountered.

For example, suppose you have the following:

if ($name == 'ktatroe')
  // do something
elseif ($name == 'rasmus')
  // do something
elseif ($name == 'ricm')
  // do something
elseif ($name == 'bobk')
  // do something

You can replace that statement with the following switch statement:

switch($name) {
  case 'ktatroe':
    // do something
    break;
  case 'rasmus':
    // do something
    break;
  case 'ricm':
    // do something
    break;
  case 'bobk':
    // do something
    break;
}

The alternative syntax for this is:

switch($name):
  case 'ktatroe':
    // do something
    break;
  case 'rasmus':
    // do something
    break;
  case 'ricm':
    // do something
    break;
  case 'bobk':
    // do something
    break;
endswitch;

Because statements are executed from the matching case label to the next break keyword, you can combine several cases in a fall-through. In the following example, "yes" is printed when $name is equal to "sylvie" or to "bruno":

switch ($name) {
  case 'sylvie': // fall-through
  case 'bruno':
    print('yes');
    break;
  default:
    print('no');
    break;
}

Commenting the fact that you are using a fall-through case in a switch is a good idea, so someone doesn't come along at some point and add a break, thinking you had forgotten it.

You can specify an optional number of levels for the break keyword to break out of. In this way, a break statement can break out of several levels of nested switch statements. An example of using break in this manner is shown in the next section.

2.5.3. while

The simplest form of loop is the while statement:

while (expression) 
  statement

If the expression evaluates to true, the statement is executed and then the expression is reevaluated (if it is true, the body of the loop is executed, and so on). The loop exits when the expression evaluates to false.

As an example, here's some code that adds the whole numbers from 1 to 10:

$total = 0;
$i = 1;
while ($i <= 10) {
  $total += $i;
}

The alternative syntax for while has this structure:

while (expr): 
  statement; 
  ...; 
endwhile;

For example:

$total = 0;
$i = 1;
while ($i <= 10):
  $total += $i;
endwhile;

You can prematurely exit a loop with the break keyword. In the following code, $i never reaches a value of 6, because the loop is stopped once it reaches 5:

$total = 0;
$i = 1;
while ($i <= 10) {
  if ($i == 5)
    break; // breaks out of the loop
  $total += $i;
  $i++;
}

Optionally, you can put a number after the break keyword, indicating how many levels of loop structures to break out of. In this way, a statement buried deep in nested loops can break out of the outermost loop. For example:

$i = 0;
while ($i < 10) {
  while ($j < 10) {
    if ($j == 5)
      break 2; // breaks out of two while loops
    $j++;
  }
  $i++;
}
echo $i; 
echo $j; 
0
5

The continue statement skips ahead to the next test of the loop condition. As with the break keyword, you can continue through an optional number of levels of loop structure:

while ($i < 10) {
  while ($j < 10) {
    if ($j = 5)
      continue 2; // continues through two levels
    $j++;
  }
  $i++;
}

In this code, $j never has a value above 5, but $i goes through all values from 0 through 9.

PHP also supports a do /while loop, which takes the following form:

do 
  statement
while (expression)

Use a do/while loop to ensure that the loop body is executed at least once:

$total = 0;
$i = 1;
do {
  $total += $i++;
} while ($i <= 10);

You can use break and continue statements in a do/while statement just as in a normal while statement.

The do/while statement is sometimes used to break out of a block of code when an error condition occurs. For example:

do {
  // do some stuff
  if ($error_condition)
    break;
  // do some other stuff
} while (false);

Because the condition for the loop is false, the loop is executed only once, regardless of what happens inside the loop. However, if an error occurs, the code after the break is not evaluated.

2.5.4. for

The for statement is similar to the while statement, except it adds counter initialization and counter manipulation expressions, and is often shorter and easier to read than the equivalent while loop.

Here's a while loop that counts from 0 to 9, printing each number:

$counter = 0;
while ($counter < 10) {
  echo "Counter is $counter\n";
  $counter++;
}

Here's the corresponding, more concise for loop:

for ($counter = 0; $counter < 10; $counter++)
  echo "Counter is $counter\n";

The structure of a for statement is:

for (start; condition; increment) 
  statement

The expression start is evaluated once, at the beginning of the for statement. Each time through the loop, the expression condition is tested. If it is true, the body of the loop is executed; if it is false, the loop ends. The expression increment is evaluated after the loop body runs.

The alternative syntax of a for statement is:

for (expr1; expr2; expr3):
  statement;
  ...;
endfor;

This program adds the numbers from 1 to 10 using a for loop:

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

Here's the same loop using the alternate syntax:

$total = 0;
for ($i = 1; $i <= 10; $i++):
  $total += $i;
endfor;

You can specify multiple expressions for any of the expressions in a for statement by separating the expressions with commas. For example:

$total = 0;
for ($i = 0, $j = 0; $i <= 10; $i++, $j *= 2) {
  $total += $j;
} 

You can also leave an expression empty, signaling that nothing should be done for that phase. In the most degenerate form, the for statement becomes an infinite loop. You probably don't want to run this example, as it never stops printing:

for (;;) {
  echo "Can't stop me!<br />";
}

In for loops, as in while loops, you can use the break and continue keywords to end the loop or the current iteration.

2.5.5. foreach

The foreach statement allows you to iterate over elements in an array. The two forms of foreach statement are discussed in Chapter 5. To loop over an array, accessing each key, use:

foreach ($array as $current) {
  // ...
}

The alternate syntax is:

foreach ($array as $current):
  // ...
endforeach;

To loop over an array, accessing both key and value, use:

foreach ($array as $key => $value) {
  // ...
}

The alternate syntax is:

foreach ($array as $key => $value):
  // ...
endforeach;

2.5.6. declare

The declare statement allows you to specify execution directives for a block of code. The structure of a declare statement is:

declare (directive) 
  statement

Currently, there is only one declare form, the ticks directive. Using it, you can specify how frequently (measured roughly in number of code statements) a tick function registered with register_tick_function( ) is called. For example:

register_tick_function("some_function");
declare(ticks = 3) {
  for($i = 0; $i < 10; $i++) {
    // do something
  }
}

In this code, some_function( ) is called after every third statement is executed.

2.5.7. exit and return

The exit statement ends execution of the script as soon as it is reached. The return statement returns from a function or (at the top level of the program) from the script.

The exit statement takes an optional value. If this is a number, it's the exit status of the process. If it's a string, the value is printed before the process terminates. The exit( ) construct is an alias for die( ):

$handle = @mysql_connect("localhost", $USERNAME, $PASSWORD);
if (!$handle) {
  die("Could not connect to database");
}

This is more commonly written as:

$handle = @mysql_connect("localhost", $USERNAME, $PASSWORD)
          or die("Could not connect to database");

See Chapter 3 for more information on using the return statement in functions.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.