Chapter 3

Using Control Structures

In This Chapter

arrow Getting used to conditions

arrow Using if, else if, and else

arrow Using switch structures

arrow Working with while and for loops

arrow Using comparison operators

Computer programs are most interesting when they appear to make decisions. PHP has many of the same decision-making structures as JavaScript, so if you've already looked over Chapters 2 and 3 of Book IV, you will find this chapter very familiar. In any case, take a look at conditions to see the key to making the computer branch and loop.

Introducing Conditions (Again)

Computer programs make decisions. That's part of what makes them interesting. But all the decisions a computer seems to make were already determined by the programmer. The computer's decision-making power is all based on an idea called a condition. This little gem is an expression that can be evaluated as true or false. (That sounds profound. I wonder if it will be on the mid-term?)

Conditions can be comparisons of one variable to another, they can be Boolean (true or false) variables, or they can be functions that return a true or false value.

remember.eps If this talk of conditions is sounding like déjà vu, you've probably read about conditions in Book IV, Chapters 2 and 3. You'll find a lot of the same ideas here; after all, conditions (and branches and loops, and lots of other stuff) are bigger than one programming language. Even though this mini-book covers a different language, you'll see coverage of the same kinds of things. If you haven't read that minibook already, you might want to look it over first so you can see how programming remains the same even when the language changes.

Building the Classic if Statement

The if statement is the powerhouse of computer programming. Take a look at Figure 3-1 to see it in action. This program might be familiar if you read Book IV already. It rolls a standard six-sided die, and then displays that die on the screen.

9781118289389-fg2701.tif

Figure 3-1: This program rolls a die. Try it again.

When it rolls a six, it displays an elaborate multimedia event, as shown in Figure 3-2. (Okay, it just says Holy Guacamole! That's a six! The dancing hippos come later …)

9781118289389-fg2702.tif

Figure 3-2: It's a six! Joy!

This program is much like the if.html program in Book IV, Chapter 3. I do all the same things here as in that program. However, PHP and JavaScript are a little different, and that's part of the game of programming. Appreciate the concepts that flow between languages while noting those details that are different.

Rolling dice the PHP way

PHP has a random number generator, which works a little differently than the one in JavaScript. The PHP version is actually easier for dice.

  $variable = rand(a, b);

This code creates a random integer between a and b (inclusive), so if you want a random 1–6 die, you can use a statement like this:

  $die = rand(1,6);

It doesn't get a lot easier than that.

Checking your six

The code for the if.php program rolls a die, displays an image, and celebrates the joyous occasion of a six.

  <!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>if.php</title>
</head>
    <title>if.php</title>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
</head>
<body>
  <h1>Try to roll a six</h1>
  <p>
    <a href = "if.php">roll again</a>
  </p>
  <?php
    //thanks to user rg1024 from openClipart.org for
    //the great dice images
    $roll = rand(1,6);
    print <<<HERE
<p>
    <img src = "images/dado_$roll.png"
         alt = "$roll"
         height = "100px"
         width = "100px" />
</p>
HERE;
    if ($roll == 6){
      print("<h1>Holy Guacamole! That's a six!</h1> ");
    } // end if
  ?>
</body>
</html>

The process is eerily familiar:

  1. Begin with a standard HTML template.

    As always, PHP is encased in HTML. There's no need to switch to PHP until you get to the part that HTML can't do: that is, rolling dice and responding to the roll.

  2. Add a link to let the user roll again.

    Add a link that returns to the same page. When the user clicks the link, the server refreshes the page and rolls a new number.

  3. Roll the rand() function to roll a die. Put the result in a variable called $roll.
  4. Print out a graphic by creating the appropriate <img> tag.

    I preloaded a bunch of die images into a directory called images. Each image is carefully named dado_1.png through dado_6.png. (Dado is Spanish for “die” — thanks to user rg1024 from openclipart.org for the great images.) To display an image in PHP, just print out a standard img tag. The URL is created by interpolating the variable $roll into the image name. Don't forget that HTML requires an alt attribute for the img tag. I just use the $roll value as the alt. That way, the die roll will be known even if the image doesn't work.

  5. Check whether the die is a six.

    This is where the condition comes in. Use the if statement to see whether the value of $roll is 6. If so, print out a message.

warning.eps The == (two equal sign) means “is equal to.” A single equal sign means assignment. If you use the single equal sign in a condition, the code may not crash, but it probably won't do what you intended.

The else clause is used when you want to do one thing if a condition is true and something else if the condition is false. The highLow.php program shown in Figure 3-3 handles this kind of situation.

The code is very similar to the if.php program.

The bold code shows the only part of the program that's new.

  <!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>highLow.php</title>
</head>
<body>
  <h1>High or low?</h1>
  <p>
    <a href = "highLow.php">roll again</a>
  </p>
  <?php
    $roll = rand(1,6);
    print <<<HERE
  <p>
      <img src = "images/dado_$roll.png"
            alt = "$roll"
            height = "100px"
            width = "100px" />
  </p>
HERE;
  if ($roll > 3){
    print "<h2>You rolled a high one</h2> ";
  } else {
    print "<h2>That's pretty low</h2> ";
  } // end if

  ?>
</body>
</html>

9781118289389-fg2703.tif

Figure 3-3: This program tells whether the roll was high or low.

Most of the code for this program is the same as the previous code example, but the condition is slightly different:

  • Now the condition is an inequality. I now use the greater-than symbol (>) to compare the roll to the value 3. You can use any of the comparison operators in Table 3-1. If $roll is higher than 3, the condition will evaluate as true, and the first batch of code will run.

    Table 3-1 Comparison Operators

    Comparison

    Discussion

    A == B

    True if A is equal to B

    A != B

    True if A is not equal to B

    A < B

    True if A is less than B (if they are numeric) or earlier in the alphabet (for strings)

    A > B

    True if A is larger than B (numeric) or later in the alphabet (string)

    A >= B

    A is larger than or equal to B

    A<= B

    A is less than or equal to B

  • Add an else clause.

    The else clause is special because it handles the situation when the condition is false. All it does is set up another block of code.

  • Include code for the false condition.

    The code between else and the ending brace for if ending brace will run only if the condition is evaluated false.

Understanding comparison operators

PHP uses many of the same comparison operators as JavaScript (and many other languages based on C). Table 3-1 summarizes these operators.

Note that PHP determines the variable type dynamically, so comparisons between numeric and string values may cause problems. It's best to explicitly force variables to the type you want if you're not sure. For example, if you want to ensure that the variable $a is an integer before you compare it to the value 4, you could use this condition:

  (integer)$a == 4

This forces the variable $a to be read as an integer. You can also use this technique (called typecasting) to force a variable to other types: float, string, or boolean.

Taking the middle road

Another variation of the if structure allows you to check multiple conditions. As an example, look at the highMidLow.php page featured in Figure 3-4.

9781118289389-fg2704.tif

Figure 3-4: Now there are three possible comments, thanks to the else if structure.

If the roll is 1 or 2, the program reports Low. If the roll is 3 or 4, it says Middle; and if it's 5 or 6, the result is High. This if has three branches. See how it works; you can add as many branches as you wish.

  <!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>highMidLow.php</title>
</head>
<body>
  <h1>High, middle, or low?</h1>
  <p>
    <a href = "highMidLow.php">roll again</a>
  </p>
  <?php
  $roll = rand(1,6);
  print <<<HERE
  <p>
    <img src = "images/dado_$roll.png"
         alt = "$roll"
         height = "100px"
         width = "100px" />
  </p>
HERE;
  if ($roll > 4){
    print "<h2>High!</h2> ";
  } else if ($roll <= 2){
    print "<h2>Low</h2> ";
  } else {
    print "<h2>Middle</h2> ";
  } // end if

  ?>
</body>
</html>

The if statement is the only part of this program that's new. It's not terribly shocking.

  1. Begin with a standard condition.

    Check whether the roll is greater than 4. If so, say High. If the first condition is true, the computer evaluates the code in the first section and then skips the rest of the while loop.

  2. Add a second condition.

    The else if section allows me to add a second condition. This second condition (roll <= 2) is evaluated only if the first condition is false. If this condition is true, the code inside this block will be executed (printing the value Low). You can add as many else if sections as you want. As soon as one is found to be true, the code block associated with that condition executes, and the program leaves the whole else system.

  3. Include an else clause to catch stragglers.

    If none of the previous conditions are true, the code associated with the else clause operates. In this case, the roll is lower than 4 and higher than 2, so report that it's in the Middle.

Building a program that makes its own form

An especially important application of the if structure is unique to server-side programming. Up to now, many of your PHP programs required two separate files: an HTML page to get information from the user and a PHP program to respond to that code. Wouldn't it be great if the PHP program could determine whether it had the data or not? If it has data, it will process it. If not, it just produces a form to handle the data. That would be pretty awesome, and that's exactly what you can do with the help of the if statement. Figure 3-5 shows the first pass of ownForm.php.

9781118289389-fg2705.tif

Figure 3-5: On the first pass, ownForm.php produces an HTML form.

The interesting thing happens when the user submits the form. The program calls itself! This time, though, ownForm recognizes that the user has sent some data and processes that information, giving the result shown in Figure 3-6.

9781118289389-fg2706.tif

Figure 3-6: Now the same program processes the data!

This program doesn't really require anything new, just a repurposing of some tools you already know. Take a look at the following code:

  <!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>ownForm.php</title>
</head>
<body>
<?php
if (filter_has_var(INPUT_POST, "userName")){
  //the form exists - process it
  $userName = filter_input(INPUT_POST, "userName");
  print "<h1>Hi, $userName</h1> ";
} else {
  //no form present, so give 'em one
  print <<<HERE
  <form action = ""
        method = "post">
    <fieldset>
      <label>Name</label>
      <input type = "text"
             name = "userName">
      <button type = "submit">
        submit
      </button>
    </fieldset>
  </form>
HERE;
} // end if

?>
</body>
</html>

Making a program “do its own stunts” like this is pretty easy. The key is using an if statement. However, begin by thinking about the behavior. In this example, the program revolves around the $userName variable. If this variable has a value, it can be processed. If the variable has not been set yet, the user needs to see a form so she can enter the data.

  1. Check for the existence of a key variable.

    Use the isset() function to determine whether the variable in question has been set. Check the $_REQUEST or one of the other superglobals ($_POST or $_GET) to determine whether the form has already been submitted. You need to check the existence of only one variable, even if the form has dozens.

  2. If the variable exists, process the form.

    If the variable exists, extract all the variables from the form and carry on with your processing.

  3. If the variable does not exist, build the form.

    If the variable does not exist, you need to make the form that will ask the user for that variable (and any others you need). Note that the action attribute of the form element should be null (““). This tells the server to re-call the same program.

technicalstuff.eps If you're using an HTML5 validator, it will complain about the empty action attribute. This is interesting because previous HTML and XHTML implementations required it in this situation. In this particular situation (a PHP program creating a form that will call the PHP program again), many web developers just live with the validator's complaints because the empty attribute explicitly defines what I want to do (call myself) and it does no harm.

Making a switch

Often, you run across a situation where you have one expression that can have many possible values. You can always use the if–else if structure to manage this situation, but PHP supplies another interesting option, shown in Figure 3-7.

9781118289389-fg2707.tif

Figure 3-7: The Magic 8 Ball uses a switch.

The code for this program uses the switch structure. Take a look at how it's done:

  <!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>switch.php</title>
</head>
<body>
<p>Ask the magic 8 ball a yes or no question!</p>
<?php
$yourNumber = rand(1,8);
switch($yourNumber){
  case 1:
    print "<p><img src="images/8ball1.png" alt = "fat chance" 
/></p>";
    break;
  case 2:
    print "<p><img src="images/8ball2.png" alt = "Yes" /></p> ";
    break;
  case 3:
    print "<p><img src="images/8ball3.png" alt = "PhD" /></p>";
    break;
  case 4:
    print "<p><img src="images/8ball4.png" alt = "You didn't say please" /></p>";
    break;
  case 5:
    print "<p><img src="images/8ball5.png" alt = "tell, then kill" /></p>";
    break;
  case 6:
    print "<p><img src="images/8ball6.png" alt = "Why trust me?" /></p>";
    break;
  case 7:
    print "<p><img src="images/8ball7.png" alt = "Ask your mother" /></p>";
    break;
  case 8:
    print "<p><img src="images/8ball8.png" alt = "The answer is in the question" /></p>";
    break;
  default:
    print "<p>An error has occurred. Please try again, or contact [email protected] for assistance. Error code: 8BIC:$yourNumber
</p>";
}
?>
<p>
  <a href="switch.php">Ask another question!</a>
</p>
</body>
</html>

The main (in fact nearly only) feature of this code is the switch statement. Here's how it works:

  1. Begin with the switch statement.

    This indicates that you will be building a switch structure.

  2. Put the expression in parentheses.

    Following the switch statement is a pair of parentheses. Put the expression (usually a variable) you wish to evaluate inside the parentheses. In this case, I'm checking the value of the variable $yourNumber.

  3. Encase the entire switch in braces.

    Use squiggle braces to indicate the entire case. As in most blocking structures, use indentation to help you remember how the structure is organized.

  4. Establish the first case.

    Put the first value you want to check for. In this situation, I'm looking for the value 1. Note that the type of data matters, so be sure you're comparing against the same type of data you think the variable will contain. Use a colon (:) to indicate the end of the case. This is one of the rare situations where you do not use a semicolon or brace at the end of a line.

  5. Write code that should happen if the expression matches the case.

    If the expression matches the case (for example, if $yourNumber is equal to 1), the code you write here will execute.

  6. End the code with the break statement.

    When you use an if-else if structure to work with multiple conditions, the interpreter jumps out of the system as soon as it encounters the first true condition. Switches work differently. Unless you specify (with the break statement), code will continue to evaluate even when one of the expressions is matched. You almost always need the break statement.

  7. Use the default clause to handle any unexpected behavior.

    The default section of the switch structure is used to handle any situation that wasn't covered by one of the previously defined cases. It's a good idea to always include a default clause.

technicalstuff.eps It may seem odd to have a default clause in this example. After all, I know how the rand() function works, and I know that I'll get values only between 1 and 8. It shouldn't be possible to have a value that isn't covered by one of the cases, yet I have a default clause in place for exactly that eventuality. Even though something shouldn't ever happen, sometimes it does. At the very least, I want a nice piece of code to explain what happened and send some kind of error message. If it's an important problem, I may have the code quietly e-mail me a message letting me know what went wrong.

tip.eps You might wonder whether the switch is necessary at all. I could have used the interpolation tricks shown in the dice example to get the necessary images. However, remember that HTML requires all images to have alt tags. With dice, the value of the roll is a perfectly acceptable alt value. The Magic 8 Ball needs to return text if the image doesn't work properly. I used a switch to ensure that I have the appropriate alt text available. (Extra points if you think an array would be an even better way to handle this situation.)

Looping with for

Sometimes you want to repeat something. PHP (like most languages) supports a number of looping constructs. Begin with the humble but lovable for loop, as shown in Figure 3-8.

9781118289389-fg2708.tif

Figure 3-8: This page prints a lot of dice with a for loop.

As you can see, Figure 3-8 prints a lot of dice. In fact, it prints 100 dice. This would be tedious to do by hand, but that's exactly the kind of stuff computers are so good at.

The following code explains all:

  <!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>for.php</title>
  <style type="text/css">
    img{
      height: 40px;
      width: 50px;
    }
  </style>
</head>
<body>
  <h1>Dice Rolling Game</h1>
  <p>Welcome to the dice rolling game. Rolling 100 dice. How many will be sixes?</p>
  <p>
  <?php
  $sixCount = 0;
  
  for ($i = 0; $i < 100; $i++){
    $userNumber = rand(1,6);
    print <<< HERE
      <img src="images/dado_$userNumber.png"
           alt = "$userNumber"
           width = "20px"
           height = "20px" />
HERE;
  
    if($userNumber == 6){
        $sixCount++;
    } // end if
  } // end for
  
  print "</p><p>You rolled $sixCount six(es)!</p>";
  ?>
  
  <p><a href="for.php">Try Again!</a></p>
 
</body>
</html>

Most of the code is plain-old HTML. Note the lone print statement responsible for printing out dice. That print statement (and a few supporting characters) are repeated 100 times. for loops are extremely powerful ways to get a lot of work done.

  1. Begin with the for keyword.

    This keyword indicates the beginning of the for structure.

      for ($i = 0; $i < 100; $i++){

  2. Add an initializer.

    for loops usually center around a specific integer variable, sometimes called the sentry variable. The first part of the for loop sets up the initial value of that variable. Often, the variable is initialized to 0 or 1.

      for ($i = 0; $i < 100; $i++){

  3. Add a condition.

    The loop continues as long as the condition is true and exits as soon as the condition is evaluated as false. Normally, the condition will check whether the variable is larger than some value.

      for ($i = 0; $i < 100; $i++){

  4. Add a modifier.

    Every time through the loop, you need to do something to change the value of the sentry. Normally, you add 1 to the sentry variable (remember, ++ is a shortcut for “add one”).

      for ($i = 0; $i < 100; $i++){

  5. Encase the body of the loop in braces.

    The code that will be repeated is placed inside braces({}). As usual, indent all code inside braces so you understand that you're inside a structure.

tip.eps for loops are first described in Book IV, Chapter 3. Please look to that chapter for more details on for loops, including how to build a loop that counts backward and counts by fives. I don't repeat that material here because for loops work exactly the same in PHP and JavaScript.

This particular program has a few other features that make it suitable for printing out 100 dice.

  • It uses $i as a counting variable. When the sentry variable's name isn't important, $i is often used. $i will vary from 0 to 99, giving 100 iterations of the loop.
  • Each time through the loop, roll a die. The familiar rand() function is used to roll a random die value between 1 and 6. Because this code is inside the loop, it is repeated.

      $userNumber = rand(1,6);

  • Print out an image related to the die roll. I use interpolation to determine which image to display. Note that I used code to resize my image files to a smaller size.

        print <<< HERE
          <img src="images/dado_$userNumber.png"
               alt = "$userNumber"
               width = "20px"
               height = "20px" />
    HERE;

  • Check whether you rolled a 6. For some strange reason, my obsession with sixes continues. If the roll is a 6, add 1 to the $sixCount variable. By the end of the loop, this will contain the total number of sixes rolled.

      if($userNumber == 6){
        $sixCount++;
    } // end if

  • Print the value of $sixCount. After the loop is completed, report how many sixes were rolled.

      print “</p><p>You rolled $sixCount six(es)!</p>“;

Looping with while

The while loop is the other primary way of repeating code. Figure 3-9 shows a variation of the dice-rolling game.

9781118289389-fg2709.tif

Figure 3-9: This time, the program continues until it gets a 6.

while loops are much like for loops. They require the same thought:

  • A sentry variable: This special variable controls access to the loop. Unlike the int usually used in for loops, the sentry of a while loop can be any type.
  • Initialization: Set the initial value of the sentry variable before the loop begins. Do not rely on default settings (because you don't know what they will be). Instead, set this value yourself.
  • A condition: The while statement requires a condition. This condition controls access to the loop. As long as the condition is true, the loop continues. As soon as the condition is evaluated as false, the loop exits.
  • A modifier: You must somehow modify the value of the sentry variable. It's important that the modification statement happen somewhere inside the loop. In a for loop, you almost always add or subtract to modify a variable. In a while loop, any kind of assignment statement can be used to modify the variable.

warning.eps for loops are a little safer than while loops because the structure of the for loop requires you to think about initialization, condition, and modification. All three features are built into the for statement. The while statement requires only the condition. This might make you think that you don't need the other parts, but that would be dangerous. In any kind of loop, you need to initialize the sentry variable and modify its value. With the while loop, you're responsible for adding these features yourself. Failure to do so will cause endless loops, or loops that never happen. See much more about this in Book IV, Chapter 3.

Take a look at the following code for the while.php program to see how it works:

  <!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>while.php</title>
  <style type="text/css">
    img {
      height: 40px;
      width: 50px;
    }
  </style>
</head>
<body>
  <h1>Dice Rolling Game 2</h1>
  <p>Welcome to the dice rolling game. See how many rolls it takes to get a six!</p>
  <div id = "output">
  <?php
  $userNumber = 999;
  $counter = 0;
  while ($userNumber != 6){
    $userNumber = rand(1,6);

    print <<< HERE
      <img src = "images/dado_$userNumber.png"
           alt = "$userNumber"
           height = "100px"
           width = "100px" />
HERE;
    $counter++;
  }
    print "<p>It took $counter tries to get a six.</p>";
  ?>
  </div>
  <p><a href="while.php">Try Again!</a></p>
</body>
</html>

This example illustrates how subtle while loops can be. All the key elements are there, but they don't all look like part of the while loop.

  1. Initialize $userNumber.

    For this loop, $userNumber is the sentry variable. The initialization needs to guarantee that the loop runs exactly once. Because the condition will be ($userNumber != 6), I need to give $userNumber a value that clearly isn't 6. 999 will do the job, and it's wild enough to be clearly out of range. Although the initialization step appears in the code before the while loop, it's often best to start with your condition and then back up a line to initialize because the initialization step depends on the condition.

  2. Set up the condition.

    Think about what should cause the loop to continue or quit. Remember that the condition explains when the loop continues. It's often easier to think about what causes the loop to exit. That's fine; just reverse it. For example, I want the loop to quit when $userNumber is equal to 6, so I'll have it continue as long as $userNumber != 6.

  3. Modify the sentry.

    This one is tricky. In this particular example, modify the sentry variable by getting a new random number: $userNumber = rand(1,6). Often in a while loop, the modification step is intrinsic to the problem you're solving. Sometimes you get the new value from the user, sometimes you get it from a file or database, or sometimes you just add (just like a for loop). The key here is to ensure you have a statement that modifies the sentry variable and that the condition can trigger. For example, using $userNumber = rand(1,5) would result in an endless loop because $userNumber could never be 6.

warning.eps while loops can cause a lot of problems because they may cause logic errors. That is, the syntax (structure and spelling of the code) may be fine, but the program still doesn't operate properly. Almost always, the problem can be resolved by thinking about those three parts of a well-behaved loop: Initialize the sentry, create a meaningful condition, and modify the sentry appropriately. See Book IV, Chapter 3 for more on while loops.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset