• Tidak ada hasil yang ditemukan

Table 5.4 Relational and logical operators, in decreasing order of precedence

Operator Description

<,<=,>,>= Relational comparisons

==,!=,===,!==,<>,<=> Relational comparisons

! Not true

&&(1) Logical AND

||(1) Logical OR

and Logical AND

xor Logical EXCLUSIVE OR

or Logical OR

(1)Note the availability of two AND (&&andand) and two OR (||and or) operators, at different precedence levels. (andandorhave lower precedence than&&and||.)

You can have as many “else if” statements as you need. For else if, writingelseif, is also acceptable. Usually, the statements to be executed in atruebranch of anifstatement are enclosed in curly brackets. If there is only one statement, the brackets are optional. Some programmers always use curly brackets even when they’re not required.

If you consider an if structure as defining branches in a road that eventually rejoin at a main road, the minimum choice is a road with no branches, where you may or may not bypass part of the road. The other option is to take one of several possible branches before rejoining with the main road.

With multiple possible branches, it is important to understand that Only the first branch of an if… statement for which the expres- sion evaluates astrue will be taken.

To use the road analogy, once you select a branch in the road, you take only that branch and no other. To make this clear, consider Document 5.2.

Document 5.2 (letterGrade.php)

<?php

$grade=87;

if($grade >= 90)echo "A<br />";

elseif($grade>= 80) echo"B<br />";

elseif($grade>= 70) echo"C<br />";

elseif($grade>= 60) echo"D<br />";

else echo"F<br />";

?>

A grade of 87 is less than 90, so thefirst branch is ignored. The second branch is true, so a“B” is displayed. 87 is also greater than 70 and 60, but these and thefinal“else”branches are ignored.

5.4 Conditional Execution 97

When comparisons get more complicated, you must be careful about how you form logical/relational expressions. Suppose you want your code to respond to the statement:“If today is Tuesday or Thursday, I should be in class.” The proper implementation is:

if (($today == "Tuesday") || ($today == "Thursday")) If this expression is rewritten as

($today == "Tuesday" || "Thursday") // don't do it!

it has a value oftrueiftodayis"Tuesday"but a value of"Thursday"

(rather than false) if today has previously been given a value of

"Monday". This is almost certainlynotwhat you intended!

An alternate version of the original expression, without the two inner sets of parentheses, is:

// OK, but not how I would do it!

($today == "Tuesday" || $today == "Thursday")

This will be interpreted correctly, but it depends on the fact that the equality operator has precedence over the OR operator. In cases like this, the author believes the use of the “extra” parentheses in the first example above is better programming style. It makes clear the order in which you wish the operations to be performed and also makes it unnecessary to memorize the precedence rules for relational and logical operators.1

Finally, consider this code fragment:

if(($today = "Tuesday") || ($today = "Thursday"))

Because the==operator is replaced with the = operator. This code doesnot compare the current value of $today with "Tuesday" or "Thursday". All it does is set the value of$todayto"Tuesday"!Do not forget that the

= operator does not mean “equals”; it is an assignment operator, with a completely different interpretation. In this context, the == operator is required to convey the sense of“is equal to.”

1It is nonetheless true that many programmersdoregularly take advantage of the precedence rules in their code.

Using an assignment operator (=) when you intend to use an equality operator (==) is a common programming mistake that is very hard tofind because it does not generate a syntax error. Be careful!

PHP also supports a“switch”construct for case-controlled conditional execution.

switch($i) { case0:

echo"i equals 0.";

break;

case1:

echo"i equals 1.";

break;

case2:

echo "i equals 2.";

break;

default:

echo"i does not equal 0, 1, or 2.";

}

The order of thecasevalues does not matter. Unlike theifconstruct, in which only the first “true” path is executed, the break; statement is needed to exit the construct after the first case match is encountered.

Otherwise, all subsequent statements within the construct are executed.

There are certainly circumstances under which this might be the desired result, in which case thebreak; statements wouldn’t be needed, although the order of thecase values probably wouldmatter.

Multiple case values can be associated with the same action, as shown in Document 5.3.

Document 5.3 (daysInMonth.php)

<?php

$month=5; // Try different values.

switch($month) { case1:

case3:

case5:

case7:

case8:

case10:

5.4 Conditional Execution 99

case12:

echo"There are 31 days in this month.<br />";break;

case4:

case6:

case9:

case11:

echo"There are 30 days in this month.<br />";break;

case2:

echo"There are either 28 or 29 days in this month.

<br />";break;

default:

echo"I do not understand your month entry.";

}

?>

PHP case values can be strings:

switch($fruit){ case"apple":

echo"This is an apple.";

break;

case"orange":

echo"This is an orange.";

break;

case"banana":

echo"This is a banana.";

break;

default:

echo"This is not an allowed fruit treat.";

}

Comparisons against the value to be tested are case-sensitive. So, if

$fruit is assigned as $fruit = "Banana"; prior to the switch con- struct, (instead of$fruit = "banana";) the default message is printed. If this is a problem, it can be overcome by using the strtolower() or strtoupper()functions.