PHP Control Flow

Chapter 8 33 mins

Learning outcomes:

  1. Selection statements — if, else and elseif
  2. Iteration statements — for, while and do...while

Introduction

In the last chapter, we came across the Boolean scalar type in PHP and mentioned that we would explore them later on. Now is the time to start exploring Booleans and working with them in this chapter where we unravel the enormous and immensely powerful world of conditional programming, or as it's known — the world of control flow.

To be specific, we'll cover the three most important selection statements in PHP — if, else and elseif, followed by the two most important iteration statements — for and while.

We'll consider tons and tons of examples and then in the upcoming exercises put our understanding of control flow to the test by solving certain tasks.

So without wasting any more of our time, let's get going...

The if statement

Often times, we want to execute a piece of code when a given condition is met.

For instance,

  1. Before showcasing a set of features to the user, we might want to check whether he/she has a premium subscription.
  2. Before signing a user into an account, we might want to check whether the entered details (such as a username and password) are correct.
  3. Before showcasing a rain alert, we might want to check for certain weather statistics that do predict rain in some way.
  4. Before exiting an application, we might want to check whether the user really wants to exit or not.

and so on and so forth.

The list of places where conditional execution is required will be, and actually is, endless. Conditions and conditional execution plays a vital role in modern-day computing.

But what allows us to check for such conditions and then lay out a block of code to execute in a given scenario is even more important, and all of this from the perspective of PHP. That's where conditional statements, also known as selection statements, come into the game.

The first selection statement that we'll consider here is if.

The if statement executes a piece of code if a given condition is true.

Here's the syntax of the if statement:

if (condition) statement;

First comes the if keyword, followed by the expression condition to test for enclosed in a pair of parentheses (()), followed by the statement to execute when the condition is true.

Here, condition is an expression.

When condition is the Boolean true or evaluates down to true in some way (based on certain rules put forward by PHP), the body of if is executed.

However, if the ain't the case i.e. the condition doesn't evaluate down to true, then the body of if is ignored and the program's execution jumps to the end of the whole if statement.

This is why we call these statements as control flow statements i.e. they control the flow of execution in a program. Cool naming, isn't this?

Let's consider a very simple example.

Suppose we want to alert the user to not forget to take an umbrella with him/her if it's a rainy day today. A variable, specifically a Boolean variable, named $is_rainy_day can be defined in this case to specify whether or not it is a rainy day today.

If the variable holds true, then it's a rainy day; otherwise it holds false and, consequently, it's not a rainy day.

For now, this is a completely hypothetical example. In a real-world weather application, there would be many real statistics that govern whether it's possible for rain to occur today or not, instead of just a mere hardcoded variable such as $is_rainy_day.

In the following code, based on the value of $is_rainy_day, we make a simple output to the user asking him/her to go out with an umbrella:

<?php

$is_rainy_day = true;

if ($is_rainy_day)
   echo "Don't forget the umbrella!";
Don't forget the umbrella!

Simple.

Let's consider another example, this time using a relational operator — the equality operator (==).

== compares two values together for equality. If both the values are equal to one another, it returns true, otherwise false.

Consider the following code:

<?php

echo 'Enter an integer: ';
$x = (int) fgets(STDIN);

if ($x % 2 == 0)
   echo 'Even';

We ask the user to enter an integer, after which we print 'Even' if the entered value is an even integer i.e. its remainder when divided by 2 is 0.

Here's a snippet of the shell after entering the value 50:

Enter an integer: 50 Even

Since 50 leaves a remainder of 0 when divided by 2, we get 'Even' printed in the terminal.

In the next section, we'll extend this code to print 'Odd' when the given condition, i.e. $x % 2 == 0, isn't met, with the help of the else statement.

The else statement

When we want to execute a piece of code upon the fulfillment of a given condition, we use if. However, when the condition isn't met, the body of if is ignored. Most importantly, the corresponding else statement is executed.

The else statement executes a piece of code if the preceding if statement fails.

Below shown is the syntax of else in PHP:

if (condition)
   statement;
else
   statement;

First comes the else keyword, followed by the statement to execute if the preceding if fails.

The else statement is not a standalone statement — it's a continuation of a preceding if statement.

Time for an example.

In the code below, we extend our rainy day alert program shown above to print another message in case there are no signs of rain today:

<?php

$is_rainy_day = false;

if ($is_rainy_day)
   echo "Don't forget the umbrella!";
else
   echo "No need for an umbrella.";
No need for an umbrella.

Since $is_rainy_day is false, the if statement fails and hence execution moves to the else statement whereby the message "No need for an umbrella." is printed.

Simple, as always!

Let's consider another example.

Below we extend our previous program, that checked whether an input integer is even, to output 'Odd' in case the integer doesn't satisfies the even test:

<?php

echo 'Enter an integer: ';
$x = (int) fgets(STDIN);

if ($x % 2 == 0)
   echo 'Even';
else
   echo 'Odd';

As before, here's a snippet of the shell after entering the value 61:

Enter an integer: 61 Odd

Since 61 leaves a remainder of 1 when divided by 2, the if statement fails and hence execution moves to the else statement, whereby the message 'Odd' is printed.

The elseif statement

When drafting some conditional code, it's not always going to be a matter of this-or-that i.e. an if followed by an else. Sometimes, we want to check for more conditions after the failure of the first if statement.

Fortunately, this can be very easily done using the elseif statement.

Syntactically, elseif is similar to if since it also involves a condition check:

if (condition1)
   statement;
elseif (condition2)
   statement;

As with else, an elseif statement can't exist on its own — it must have a preceding if statement. Moreover, for every if, we can have as many corresponding elseif statements as we like.

Let's consider a quick example.

Suppose we want to show to the user the rating for a particular item they are inspecting in an online store. The rating is represented as an integer between 1 - 3. 1 stands for 'Not Good', 2 stands for 'Average', and 3 stands for 'Good'.

We have to write some PHP code such that, given a rating integer, it prints the corresponding rating text, as described above.

The following code is where to begin. Here we assume that the rating is provided to us in the form of a variable $rating:

<?php

$rating = 2;

So, how to solve this problem?

Well, we need to check for just two cases, after which we know we are left with only one case. In other words, we need to use an if, an elseif, and an else statement.

Here's the code:

<?php

$rating = 2;

if ($rating === 1)
   echo 'Not Good';
elseif ($rating === 2)
   echo 'Average';
else
   echo 'Good';

Let's review how this code works:

First it's checked whether $rating is equal to 1. If it is, the text 'Not Good' is printed. Otherwise, it's then checked whether $rating is equal to 2. If it is, the text 'Average' is printed. If none of these conditions are fulfilled, the text 'Good' is printed.

In our case, since $rating is 2, we get 'Average' printed:

Average

Easy, wasn't it?

One thing to note in the code above is that we have jam-packed each of the selection statements into one another. As you may agree, this reduces the readability of the code.

A much better and readable approach is to add whitespace between each selection statement, as shown below:

<?php

$rating = 2;

if ($rating === 1)
   echo 'Not Good';

elseif ($rating === 2)
   echo 'Average';

else
   echo 'Good';

So this was it for the selection statements if, else and elseif.

In the PHP Control Flow unit, we'll dive into even more details of these three statements, and then consider another, more complex, selection statement called switch.

The for loop

Apart from selection statements, another vital category of statements in PHP is that of iteration statements, also known as looping statements.

Looping, or iteration, is the key to computer automation. It is when a computer executes some piece of code over and over again until some termination point is reached.

In PHP, as is typical in most languages, we have two statements that enable iteration — for and while. In this section, we shall explore for on the outskirts, before moving over to while in the next section.

The for loop is meant to execute a given piece of code a known number of times.

Here, 'a known number of times' could mean 10 times, 100 times, 1,000,000 times, or maybe as many times as the length of a string, or an array, and so on.

Here's the general syntax of for:

for (initialization; condition; update)
   statement;

It all starts with the for keyword. Then comes a pair of parentheses (()) enclosing a set of configurations for the loop, each separated by a semicolon (;).

  1. The first of these configurations is initialization. Here we place the expression creating given variables needed for the functioning of the loop.
  2. The second is the condition. This is the expression that should evaluate to true in order for the loop to continue with the next iteration.
  3. The third is the update expression. Here, we update any variables that are used by the loop.

After this set of configurations, we finally have the statment to execute in each iteration of the loop.

Akin to selection statements, the very starting segment of for is called the header of the loop, while the following block of code that ultimately gets executed each time is called the body of the loop.

Now, it's time to understand how all this works together.

Let's suppose that we want to print the first three non-negative integers. This is quite easy to do all by hand. However, we'll use a for loop to do so as shown below:

<?php

for ($i = 0; $i < 3; $i++)
   echo $i, "\n";

The expression $i++ here simply serves to increment $i by 1. Semantically, it's identical to $i = $i + 1.

The output produced is as follows:

0 1 2

Now let's see how this code works:

  1. At the beginning of the for loop, the initialization expression $i = 0 is executed. This creates a variable $i and sets it to 0. After this, the loop begins.
  2. Before proceeding with the iteration, the condition $i < 3 is evaluated. Since, at this stage, $i < 3 translates to 0 < 3 (since $i is equal to 0), the condition evaluates to true. Hence, the iteration begins.
  3. The statement echo $i, "\n" is executed and this prints 0 to the terminal. At the end, $i is incremented to 1 via $i++. Let's move on.
  4. Before proceeding with the next iteration, the condition $i < 3 is evaluated. Since, at this stage, $i < 3 translates to 1 < 3 (since $i is equal to 1), the condition evaluates to true. Hence, the next iteration begins.
  5. The statement echo $i, "\n" is executed and this prints 1 to the terminal. At the end, $i is incremented to 2 via $i++. Let's move on.
  6. Once again, before proceeding with the next iteration, the condition $i < 3 is evaluated. Since, at this stage, $i < 3 translates to 2 < 3 (since $i is equal to 2), the condition evaluates to true. Hence, the next iteration begins.
  7. The statement echo $i, "\n" is executed and this prints 2 to the terminal. At the end, $i is incremented to 3 via $i++. Let's move on.
  8. Before proceeding with the next iteration, the condition $i < 3 is evaluated. Since, at this stage, $i < 3 translates to 3 < 3 (since $i is equal to 1), the condition evaluates to false. Hence, the loop exits i.e. its execution completes.

This is how for works under the hood.

Let's consider another example.

In the following code, we iterate over an array and print each of its items one-by-one on a newline:

<?php

$nums = [1, 5, -8, 9];

for ($i = 0; $i < count($nums); $i++)
   echo $nums[$i], "\n";
1 5 -8 9

Here $i acts as the index of each subsequent item in the given array. It starts at 0 and goes upto (but excluding) count($nums) (i.e. the total number of items in $nums). That is, $i starts at 0, goes to 1, then 2, then 3, and then the loop exits.

The while loop

Another way to iterate in PHP is using the while loop.

It behaves a bit differently than for, with a different syntax; nonetheless, it's still very easy to get the hang of just like for.

First, let's see what is really is:

The while loop executes a piece of code an unknown number of times until some condition doesn't become false.

Below shown is the syntax of while:

while (condition)
   statement;

The while loop's body keeps on executing as long as the given condition remains true. It only terminates when the given condition becomes false.

The while loop resembles English language particularly well — 'while this condition is true, keep on doing this...'

Difference between for and while in PHP

Theoretically, both for and while operate on the same principle i.e. until some condition does not become false, just keep on iterating.

In fact, this is how any computer in this world can iterate over code!

They only differ from one another syntactically, one suiting a given purpose and the other suiting another.

  1. for is meant to go over sequences (such as strings, arrays, etc.) and ranges (such as 1 - 100).
  2. while is meant to monitor certain events and exit when it gets to see a termination point in those events.

Let's take a very simple example.

Let's suppose that we ask the user to input the name of the programming language they like the most. Chances are that the user enters an empty value and tries to trick the program into thinking that the empty input is a valid programming language's name.

To mitigate such an issue, we can use a while loop that keeps on asking the user to enter the language's name until and unless the input is not empty.

In the code below, we do exactly this:

<?php

echo "Your favorite language: ";
$lang = rtrim(fgets(STDIN));

while ($lang == '') {
   // Invalid input message.
   echo "Empty string doesn't work. Please input again.\n\n";

   // Repeat the input prompt.
   echo "Your favorite language: ";
   $lang = rtrim(fgets(STDIN));
}

echo $lang, " is your favorite language.";

Let's see what's happening here.

First, we print a prompt asking the user to input his/her favorite language, followed by laying out a call to fgets() for retrieving the input.

Note the call to rtrim(). This is a new function that simply serves to trim whitespace (including newlines) off from the end of the given string.

In our case, we pass the result of fgets() to rtrim() because of one reason — the last character in any input is \n (which results from the press of the Enter key) and thus must be trimmed away so that we can easily join it with other strings without posing any formatting errors in the output.

In the while loop, we check if the entered input (after the trimming) is empty. If it is, we make the input prompt again after printing an error message.

Simple!

Time to try out this code:

Your favorite language: Empty string doesn't work. Please input again. Your favorite language: C C is your favorite language.

First, we input nothing and press Enter. This is invalid for the program and consequently it displays the error message detailing about the problem before asking for the input again. The second time we enter 'C' and thus cause the program to end with printing 'C is your favorite language'.

One thing to note here is that line 12 plays an essential role in the correct working of the program. If we omit it, we'd run into one of the most prevalent problems when working with loops — an infinite loop.

Try running the following code:

<?php

echo "Your favorite language: ";
$lang = rtrim(fgets(STDIN));

while ($lang == '') {
   // Invalid input message.
   echo "Empty string doesn't work. Please input again.\n\n";

   // Repeat the input prompt.
   echo "Your favorite language: ";
}

echo $lang, " is your favorite language.";

Once you press Enter while having entered nothing, the code would just go on forever, filling the screen with output messages laid out in the code itself.

To stop this infinite loop, we ought to forcefully exit the program, which is usually done by pressing Ctrl + C in the terminal.

Infinite loops are commonly witnessed as programmers construct while loops — even the pros out there can end up writing infinite loops — since setting them can involve a lot of details; and where there are details, there are errors.

Debugging infinite loops is a painful task especially if the loop works around many values in a complicated manner. We'll learn more about debugging later on in this course.

The do...while loop

Often times, when working with loops, we want to execute a piece of code and then check a certain condition before continuing on with the same piece of code in the loop.

For instance, consider the code below:

<?php

echo 'Please enter 0 > ';
$input = rtrim(fgets(STDIN));

while ($input !== '0') {
   echo 'Please enter 0 > ';
   $input = rtrim(fgets(STDIN));
}

echo "You entered '0'";

First, outside the loop, we make an input prompt and consequently retrieve input from the user. Then execution tips into the loop beginning at its condition. If 0 is not entered, the loop's body executes. However, if 0 is entered, the loop completes and consequently the final output is made.

Here's how the code runs:

Please enter 0 > 5 Please enter 0 > true Please enter 0 > random Please enter 0 > Hello World! Please enter 0 > 0 You entered '0'

The main thing to notice here is that we are repeating the input-retrieving statements twice — one outside the loop (lines 3 - 4) and one inside the loop (lines 7 - 8). The set of statements outside the loop is only given in order to set up the variable used in the loop's main condition i.e. $input.

Another way is to preset the variable $input to a value that causes the loop's condition to be met so that the first iteration happens. This effectively prevents repeating the loop's body outside the loop.

In the code below, we take exactly this approach:

<?php

// Preset to run the loop at least once.
$input = NULL;

while ($input !== '0') {
   echo 'Please enter 0 > ';
   $input = rtrim(fgets(STDIN));
}

echo "You entered '0'";

We preset $input to NULL so that the loop's body executes at least once.

Technically, $input could be preset to anything that's not '0' i.e. 1, false, true, 'random', [], but using NULL is a bit more logical than using any arbitrary value.

Now despite the fact that this code snippet solves the code repetition problem, PHP provides an even more elegant construct for the same purpose — the do...while loop.

The do...while loop executes a piece of code until some condition doesn't become false, where the condition is checked after the code executes.

The only difference between while and do...while is that while checks the condition before executing its body whereas do...while checks the condition after executing its body. In either case, if the condition is met, the next iteration is put in place.

Simple.

Syntactically, do...while looks like this:

do
   statement;
while (condition);

Even syntactically the fact that the code executes first and then the condition evaluated is made clear.

So in short, do...while allows one to execute the body of the loop at least once.

Let's rewrite the code above using do...while instead of while with a preset variable:

<?php

do {
   echo 'Please enter 0 > ';
   $input = rtrim(fgets(STDIN));
}
while ($input !== '0');

echo "You entered '0'";
Please enter 0 > 5 Please enter 0 > true Please enter 0 > random Please enter 0 > Hello World! Please enter 0 > 0 You entered '0'

Notice how we don't need to preset $input to anything — the loop's body takes care of setting up $input. This is clearly much better than the previous approach.

Perfect!