Overview
So far you've written some PHP programs that get information from the user, store things in variables, and do some simple operations on those variables. Most of the really interesting things you can do with a computer involve letting it make decisions. Actually, the computer only appears able to decide things. The programmer generates code that tells the computer exactly what to do in different circumstances. In this chapter, you'll learn how to control the flow of a program. Specifically, you'll learn how to:
Create a random integer.
Use the if structure to change the program's behavior.
Write conditions to evaluate variables.
Work with the else clause to provide instructions when a condition is not met.
Use the switch statement to work with multiple choices.
Build functions to better manage your code.
Write programs that can create their own forms.
Examining the "Petals Around the Rose" Game
The Petals Around the Rose game, featured in Figure 3.1 illustrates all the new skills you will learn in this chapter.
Figure 3.1: This is a new twist on an old dice puzzle.
The premise of the Petals game is very simple. The computer rolls a set of five dice and asks the user to guess the number of "petals around the rose."
The user enters a number and presses the button. The computer then indicates whether this value was correct, and provides a new set of dice.
Once the user understands the secret, it's a very easy game, but it can take a long time to figure out how it works. When you look at the code towards the end of this chapter, you'll learn the secret, but for now you should try the game yourself before you know how it's done.
Creating a Random Number
The dice game, like many other games, relies on random number generation to make things interesting. Most languages have at least one way to create random numbers. PHP makes it very easy to create random numbers with the rand function.
Viewing the "Roll 'em" Program
The roll' em program shown in Figure 3.2 demonstrates how the rand function can be used to generate virtual dice.
Figure 3.2: The die roll is randomly generated by
PHP.
The code for the rollEm program shows how easy random number generation is.
<html>
<head>
<title>Roll Em!</title>
</head>
<body>
<h1>Roll Em!</h1>
<h3>Demonstrates rolling a die</h3>
<?
$roll = rand(1,6);
print "You rolled a $roll";
print "<br>";
print "<img src = die$roll.jpg>";
?>
<br>
Refresh this page in the browser to roll another die.
</body>
</html>
I used the rand function to generate a random number between one and six (inclusive) and stored the resulting value in the $roll variable. The rand function expects two parameters. The first value is the lowest number you wish, and the second value represents the highest number. Since I want to
replicate an ordinary six-sided die, I told the rand function to return a value between one and six. Since I knew that rand would return a value, I assigned that resulting value to the variable $roll. By the time the line
$roll = rand(1,6);
has finished executing, the $roll variable will have a random value in it.
The lowest possible value will be one, the highest possible value will be six, and the value will not have a decimal part. (In other words, it will never be 1.5.)
Printing a Corresponding Image
Notice the sneaky way I used variable interpolation. I carefully named my first image die1.jpg, the second die2.jpg, and so on. When I was ready to print an image to the screen, I used an ordinary HTML image tag, but the source is set to die$roll.jpg. If $roll is three, the image will show die3.jpg.
You'll see some other ways to let the computer respond to random numbers shortly, but variable interpolation can be a wonderful trick if you know how the file names are structured.
ACQUIRING IMAGES
The dice games in this chapter demonstrate the power of graphical images to make your programs more interesting and fun. There are a number of ways to get graphics for your programs. The easiest is to find an existing image on the Web. Although this is technically very simple, many of the images on the Web are owned by somebody, so you should try to respect the intellectual property rights of the original owners. Try to get permission for any images you use.
Another alternative is to create the graphics yourself. Even if you don't have any artistic talent at all, modern software and technology make it quite easy to generate passable graphics. You can do a lot with a digital camera and a freeware graphics editor. Even if you will hire a
professional artist to do graphics for your program, you might still need to be able to sketch what you are looking for. We've added a couple of very powerful freeware image editing programs to the CD-Rom that accompanies this book.
TRICK If you're coming from another programming language, you might be a little surprised at the way random numbers are generated in PHP. Most languages allow you to create a random floating point value between zero and one, and then require you to transform that value to whatever range you wish. PHP allows (in fact requires) you to create random integers within a range, which is usually what you want anyway. If you really want a value between zero and one, you can generate a random number between zero and 1000 and then divide that value by 1000.
HINT You might recall from Chapter 2, "Using Variables and Input" that interpolationis the technique that allows you to embed a variable in a quoted string by simply using its name.
Using the if Statement to Control Program Flow
One of the most interesting things computers do is appear to make decisions. The decision-making ability of the computer is really an illusion.
The programmer stores very specific instructions inside a computer, and it acts only on those instructions. The simplest form of this behavior is a structure called the if statement.
Introducing the Ace Program
I'll slightly modify the "roll-em" program to illustrate how it can be improved with an if structure. Figure 3.3 shows the program when the program rolls any value except one.
Figure 3.3: When the roll is not a one, nothing interesting
happens.
However, this program does something exciting (okay, moderately exciting) when it rolls a one, as you can see from Figure 3.4.
Figure 3.4: When a one appears, the user is treated to a lavish
multimedia display.
Creating a Condition
On the surface, the behavior of the Ace program is very straightforward: it does something interesting only if the die roll is one, and it doesn't do that interesting thing in any other case. While it is a simple idea, the implications are profound.
The same simple mechanism used in the Ace program is the foundation of all complicated computer behavior, from flight simulators to heart monitors.
Take a look at the code for the Ace program and see if you can spot the new element:
<html>
<head>
<title>Ace!</title>
</head>
<body>
<h1>Ace!</h1>
<h3>Demonstrates if statement</h3>
<?
$roll = rand(1,6);
print "You rolled a $roll";
if ($roll == 1){
print "<h1>That's an ace!!!!!</h1>";
} // end if
print "<br>";
print "<img src = die$roll.jpg>";
?>
<br>
Refresh this page in the browser to roll another die.
</body>
</html>
The secret to this program is the segment that looks like this:
if ($roll == 1){
print "<h1>That's an ace!!!!!</h1>";
} // end if
The line that prints "That's an ace!" will not happen every time the program is run. It will only happen if a certain condition is true. The if statement sets up a condition for evaluation. In this case, the condition is read "$roll is equal to one." If that condition is true, all the code between the left brace ({) and the right brace (}) will evaluate. If the condition is not true, the code between the braces will be skipped altogether.
A condition can be thought of as an expression that can be evaluated as true or false. Any expression that can return a true or false value can be used as a condition. Most conditions look much like the one in the Ace program. This condition checks the variable $roll to see if it is equal to the value 1.
Note that equality is indicated by two equals signs (==).
This is important, because computer programs are not nearly as flexible as humans. We humans often use the same symbol for different purposes.
While computer languages can do this, it often leads to problems. The single
equals sign is reserved for assignment. You should read this line
$x = 5;
as xgets five, indicating that the value five is being assigned to the variable $x. The code fragment
$x == 5;
should be read as x is equal to five, as it is testing equality. It is essentially asking whether x is equal to five. A condition such as $x == 5 does not stand on its own. Instead, it is used inside some sort of other structure, such as an if statement.
Exploring Comparison Operators
Equality (==) is not the only type of comparison PHP allows. There are several other ways to compare a variable and a value or two variables.
These comparison operators are described in table 3.1
These comparison operators work on any type of data, although the results might be a little strange. For example, if you have a condition like
"a" < "b"
you would get the result true because alphabetically, the letter "a" is earlier than "b," so it has a "smaller" value.
Creating an if Statement
An if statement begins with the keyword if followed by a condition inside parentheses. After the parentheses is a left brace ({). You can put as many lines of code between the left brace and the right brace(}) as you wish. Any code between the braces will only be executed if the condition is true. If the condition is false, program control flows to the next line after the right brace.
It is not necessary to put a semicolon on a line ending with a brace. It is customary to indent all the code between the left brace and the right brace.
CODE STYLE
You might be aware that the PHP processor actually ignores the spaces and carriage returns in your PHP code, so you might wonder if it matters to pay such attention to how code is indented, where the braces go, and so on. While the PHP processor doesn't care how you format your code, human readers do. Programmers have passionate arguments about how you should format your code. If you are writing code with a group (for instance in a large project or for a class), you will often be given a style guide you are expected to follow. When you're working on your own, the Table 3.1: COMPARISON OPERATORS
Operator Description
== equal to
< less than
> greater than
<= less than or equal to
>= greater than or equal to
!= not equal to
specific style you adopt is not as important as staying with it and being consistent in your coding. The particular stylistic conventions I have adopted for this book are reasonably common, relatively readable (especially for beginners), and easily adapted to a number of languages.
If you don't have your own programming style, the one presented in this book is a good starting place. However, if your team leader or teacher requires another style, you will need to adapt to it. Regardless of the specific style guidelines you use, it makes lots of sense to indent your code, place comments liberally throughout your program, and use white space to make your programs easier to read and debug.
TRAP Do not put a semicolon at the end of the if line. The following code if ("day" == "night") ; {
print "we must be near a black hole";
} // end if
will print "we must be near a black hole." When the processor sees the semicolon following ("day" == "night"), it thinks there is no code at all to evaluate if the condition is true, so the condition is effectively ignored.
Essentially, the braces are used to indicate that an entire group of lines are to be treated as one structure, and that structure is part of the current logical line.
Working with Negative Results
The Ace program shows how to write code that handles a condition. Much of the time, you'll want the program to do one thing if the condition is true, and something else if the condition is false. Most languages include a special variant of the if statement to handle exactly this type of contingency.
Demonstrating the Ace or Not Program
The Ace or Not program is built from the Ace program, but it has an important difference, as you can see from Figures 3.5 and 3.6.
Figure 3.5: If the program rolls a "one," it still hollers out
"Ace!"
Figure 3.6: If the program rolls anything but a one, it still has a message
for the user.
In other words, the program does one thing when the condition is true and something else when the condition is false.
Using the else Clause
The code for the aceOrNot program shows how the else clause can be used to allow for multiple behavior.
<html>
<head>
<title>Ace or Not</title>
</head>
<body>
<h1>Ace or Not</h1>
<h3>Demonstrates if statement with else clause</h3>
<?
$roll = rand(1,6);
print "You rolled a $roll";
print "<br>";
if ($roll == 1){
print "<h1>That's an ace!!!!!</h1>";
} else {
print "That's not an ace...";
} // end if
print "<br>";
print "<img src = die$roll.jpg>";
?>
<br>
Refresh this page in the browser to roll another die.
</body>
</html>
The interesting part of this code comes near the if statement:
if ($roll == 1){
print "<h1>That's an ace!!!!!</h1>";
} else {
print "That's not an ace...";
} // end if
If the condition $roll == 1 is true, the program prints "That's an ace!!!!!" If the condition is not true, the code between else and the end of the if structure is executed instead. Notice the structure and indentation. One chunk of code (between the condition and the else statement, encased in braces) occurs if the condition is true. If the condition is false, the code between else and the end of the if structure (also in braces) is executed.
You can put as much code in either segment as you wish. Only one of the segments will run (based on the condition), but you are guaranteed that one will execute.
Working with Multiple Values
Often you will find yourself working with more complex data. For example, you might want to respond differently to each of the six possible rolls of a die. The Binary Dice program illustrated in Figures 3.7 and 3.8 demonstrates just such a situation.
Figure 3.7: The roll is a 5, and the program shows the binary representation of that value.
Figure 3.8: After rolling again, the program again reports the binary representation of the new roll.
Writing the Binary Dice Program
This program has a slightly more complex if structure than the others, because the binary value should be different for each of six possible
outcomes. An ordinary if structure would not be sufficient, but it is possible to put several if structures together to solve this kind of dilemma.
<html>
<head>
<title>Binary Dice</title>
</head>
<body>
<h1>Binary Dice</h1>
<h3>Demonstrates multiple if structure</h3>
<?
$roll = rand(1,6);
print "You rolled a $roll";
print "<br>";
if ($roll == 1){
$binValue = "001";
} else if ($roll == 2){
$binValue = "010";
} else if ($roll == 3){
$binValue = "011";
} else if ($roll == 4){
$binValue = "100";
} else if ($roll == 5){
$binValue = "101";
} else if ($roll == 6){
$binValue = "110";
} else {
print "I don't know that one...";
} // end if
print "<br>";
print "<img src = die$roll.jpg>";
print "<br>";
print "In binary, that's $binValue";
print "<br>";
print "<br>";
print "<br>";
?>
<br>
Refresh this page in the browser to roll another die.
</body>
</html>
Using Multiple else if Clauses
The binaryDice program still has only one if structure, but that structure has multiple else clauses. The first condition simply checks to see if $roll is equal to one. If it is, the appropriate code runs (assigning the binary representation of 1 to the $binValue variable.) If the first condition is false, the program looks at all the successive if else clauses until it finds a condition that evaluates to true. If none of the conditions is true, the code in the else clause will be executed.
TRICK You may be surprised that I even put an else clause in this code. Since you know the value of $roll must be between one and six, and we've checked each of those values, the program should never need to evaluate the else clause. Things in programming don't always work out the way you expect, so it's a great idea to have some code in an else clause even if you don't expect to ever need it. It's much better to get a message from your program explaining that something unexpected occurred than to have your program blow up inexplicably while your users are using it.
The indentation for a multiple-condition if statement is useful so you can tell which parts of the code are part of the if structure, and which parts are meant to be executed if a particular condition turns out to be true.
Using the switch Structure to Simplify Programming
The situation in the Binary Dice program happens often enough that another structure is designed for exactly this kind of case, when you are comparing one variable to a number of possible values. The Switch Dice program shown in Figure 3.9 looks identical to the Binary Dice program as far as the user is concerned, except it shows the Roman numeral representation of the die roll instead of the binary version.
Figure 3.9: This version shows a die roll in Roman
numerals.
While the outward appearance of the last two programs is extremely similar, the underlying structure of the code is changed to illustrate a very handy device called the switch structure.
Building the Switch Dice Program
The code of the Switch Dice program looks different than the Binary Dice demo, but the results are the same.
<html>
<head>
<title>Switch Dice</title>
</head>
<body>
<h1>SwitchDice</h1>
<h3>Demonstrates switch structure</h3>
<?
$roll = rand(1,6);
print "You rolled a $roll";
print "<br>";
switch ($roll){
case 1:
$romValue = "I";
break;
case 2:
$romValue = "II";
break;
case 3: