Control Structures

 

Control flow structures are language constructs which control the flow of the program – i.e. they control what lines of the source code get executed. Important control flow constructs:

  • conditions – if, switch (and case)
  • loops – for, foreach, while (and do-while)

Conditions

In PHP conditional statements are written using ifelse reserved words.

<?php 

$numberOfWheels = 4;

if ($numberOfWheels == 4) {
    echo "It's a car.";
} else {
	echo "It is something else";
}

The condition itself must be always in parentheses. Multiple conditions can be joined using boolean operators && (and) and || (or) (there are other confusing boolean operators in PHP), negation is written using !. Do not confuse boolean logical operators with bitwise operators.

<?php

$numberOfWheels = 4;
$drive = 'electric';

if (($numberOfWheels == 4) && ($drive == 'electric')) {
    echo "It's an electric car.";
} elseif (($numberOfWheels == 4) && ($drive == 'combustion')) {
    echo "It's a smoking car.";
} else if (($numberOfWheels == 4) && ($drive == 'feet')) {
    echo "It's a Flintstones car.";
} elseif ($numberOfWheels == 2) {
    echo "It's a bike.";
} else if ($numberOfWheels == 1) {
    echo "It's a unicycle.";
} else {
    echo "I don't know what that is.";
}

You can write either elseif or else if, there is no difference.

Switch – Case

The above example can be rewritten using switchcase statements:

<?php

$numberOfWheels = 4;
$drive = 'electric';

switch ($numberOfWheels) {
    case 4:
        switch ($drive) {
            case 'electric':
                echo "It's an electric car.";
                break;
            case 'combustion':
                echo "It's a smoking car.";
                break;
            case 'feet':
                echo "It's a Flintstones car.";
                break;
            default:
                echo "It's an unknown car.";
        }
        break;
    case 2:
        echo "It's a bike.";
        break;
    case 1:
        echo "It's a unicycle.";
        break;
    default:
        echo "I don't know what that is.";
}

Note that it is important to put break in each branch, which terminates the switch execution (otherwise all consecutive branches will get executed too). The break at the end of the case 4 statement is especially tricky.

Comparison vs. Assignment

When comparing two values, you must use the comparison operator ==. If you use the assignment operator, you might run into an unexpected behavior. If you write:

if ($numberOfWheels = 4) {  //assigns 4 into variable and evaluates the variable as truthy
    echo "It's a car.";
}

The above condition is always true (regardless of the actual value of $numberOfWheels). This is because the value of assignment is the assigned value, so the condition (after evaluating the part in parentheses) will be if (4) {. Now the boolean type conversion kicks in and converts 4 to boolean, and according to the rules 4 is not false, so it is true. That’s unexpected and somewhat dangerous, good development tools will warn you about this.

Sometimes this is prevented by writing conditions in reverse order if (4 == $numberOfWheels). Because in this case, using a single = – i.e. if (4 = $numberOfWheels) will cause a compilation error (you cannot assign anything to the constant number 4). Personally I find this way of writing weird.

Loops

A loop executes a piece of a code multiple times in so called iterations. An iteration is one single execution of the loop body. There are three basic loops in PHP as in C:

<?php

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

$j = 0;
while ($j < 10) {
	echo $j;
	$j++;
}

$k = 0;
do {
	echo $k;
	$k++;
} while ($k < 10);

All three loops are equivalent, so the above will output ‘012345678901234567890123456789’. for is used when the number of iterations is known beforehand (like in the above example), as it is the simplest of the three. while is used when the terminating condition must be evaluated before the iteration is executed. do-while is used when the termination condition can be evaluated only after the iteration is executed. PHP also has a special foreach loop which we’ll attend to later.

Using break and continue

You can break the loop using break keyword. Once used, the iteration is stopped and code execution skips to the next line after the loop:

//this code will print 012345end of script
for($i = 0; $i < 10; $i++) {
    if($i == 6) {
        break;
    }
    echo $i;
}
echo 'end of script';

There is also continue keyword which skips just one iteration of the loop:

//this code will print 012345789end of script
for($i = 0; $i < 10; $i++) {
    if($i == 6) {
        continue;
    }
    echo $i;
}
echo 'end of script';

Task

Take the contact form from the previous chapter and:

  • Assume that you have the variable $currentUser with the name of the currently logged user or an empty string in case no one is logged.
  • If the user is logged in, display a greeting for him and hide the email input.
  • If the user is not logged in, show the email input and year of birth select box.
  • Fill the year of birth select box with the year from 1916 up to the current year (use date('Y') to obtain the current year)

You will need to define the variable $currentUser and test it with different values. So with $currentUser = 'John Doe'; the form should look like this:

Screenshot -- Introduction page

And with $currentUser = ''; the form should look like this:

Screenshot -- Introduction page

<?php

$rows = 10;
$cols = 50;
$message = "Hello,\nI'd like to know more about your product &lt;ProductName&gt;\n\nBest Regards,\n&lt;YourName&gt;";
$pageTitle = "Contact form";
$currentUser = "John Doe";

$currentYear = date('Y');

echo "<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'>
        <title>$pageTitle</title>
    </head>
    <body>
        <h1>$pageTitle</h1>";
        if ($currentUser != '') {
            echo "<h2>Hello $currentUser</h2>";
        }
        echo "
    	<form method='post' action='http://odinuv.cz/form_test.php'>
    		<ul>";
            if ($currentUser == '') {
                echo "
    			<li>
    				<label>E-mail address:
    					<input type='email' name='email'>
    				</label>
    			</li>
                <li>
                    <label>Year of birth:
                        <select name='year'>";
                        for ($year = 1916; $year < $currentYear; $year++) {
                            echo "<option value='$year'>$year</option>";
                        }
                        echo "
                        </select>
                    </label>
                </li>
                ";
            }
            echo "
    			<li>
    				<label>Message for us:
    					<textarea name='message' cols='$cols' rows='$rows'>$message</textarea>
    				</label>
    			</li>
    		</ul>
    		<button type='submit' name='contactButton' value='contact'>Contact Us</button>
    	</form>
	</body>
</html>";

As you can see, the script is getting rather complicated – especially the concatenation of the strings. From now on, we will be working on simplifying the code. Again, there are many different solutions.

Summary

Now you should be able to control the flow of your application. This means using conditional branching and loops.

New Concepts and Terms

  • Conditionals – if, else, ifelse, switch, case
  • Loops – for, while, do-while
  • Comparison vs. Assignment

Control question

  • Is it possible to use assignment operator inside control structure (e.g. if($a = 5) {})?
  • Does every if has to have else?
  • What is considered to be non-true value?