CHAPTER 2-3 – PHP 5 Basic Language
Operator Name Value == Equal to Checks for equality between two arguments performing type conver- sion when necessary: 1 == "1" results in true 1 == 1 results in true != Not equal to Inverse of ==. > Greater than Checks if first operand is greater than second < Smaller than Checks if first operand is smaller than second >= Greater than or equal to Checks if first operand is greater or equal to second <= Smaller than or equal to Checks if first operand is smaller or equal to second For the following two operators, automatic type conversions are not per- formed and, therefore, both the types and the values are compared. Operator Name Value === Identical to Same as == but the types of the operands have to match. No automatic type conver- sions are performed: 1 === "1" results in false. 1 === 1 results in true. !== Not identical to The inverse of ===.
2.6.4 Logical Operators Logical operators first convert their operands to boolean values and then perform the respective comparison.
Operator Name Value &&, and Logical AND The result of the logical AND operation between the two operands ||, or Logical OR The result of the logical OR operation between the two operands xor Logical XOR The result of the logical XOR operation between the two operands 2.6.4.1 Short-Circuit Evaluation When evaluating the logical and/or opera- tors, you can often know the result without having to evaluate both operands. For example, when PHP evaluates 0 && 1, it can tell the result will be false by looking only at the left operand, and it won't continue to evaluate the right one. This might not seem useful right now, but later on, we'll see how we can use it to execute an operation only if a certain condition is met. 2.6.5 Bitwise Operators Bitwise operators perform an operation on the bitwise representation of their arguments. Unless the arguments are strings, they are converted to their corresponding integer representation, and the operation is then per- formed. In case both arguments are strings, the operation is performed between corresponding character offsets of the two strings (each character is treated as an integer). Operator Name Value & Bitwise AND Unless both operands are strings, the integer value of the bitwise AND operation between the two operands. If both operands are strings, a string in which each character is the result of a bitwise AND operation between the two corresponding characters in the operands. In case the two operand strings are different lengths, the result string is truncated to the length of the shorter operand.
| Bitwise OR Unless both operands are strings, the integer value of the bitwise OR operation between the two operands. If both operands are strings, a string in which each character is the result of a bitwise OR operation between the two corresponding characters in the operands. In case the two operand strings are of different lengths, the result string has the length of the longer oper- and; the missing characters in the shorter operand are assumed to be zeros. ^ Bitwise XOR Unless both operands are (exclusive or) strings, the integer value of the bitwise XOR operation between the two operands. If both operands are strings, a string in which each character is the result of a bitwise XOR operation between the two cor- responding characters in the operands. In case the two oper- and strings are of different lengths, the result string is truncated to the length of the shorter operand.
2.6.6 Unary Operators Unary operators act on one operand.
2.6.7 Negation Operators Negation operators appear before their operand--for example, !$var (! is the operator, $var is the operand). Operator Name Value ! Logical Negation true if the operand evalu- ates to false. False if the operand eval- uates to true.
~ Bitwise Negation In case of a numeric oper- and, the bitwise negation of its bitwise representa- tion (floating-point values are first converted to integers). In case of strings, a string of equal length, in which each character is the bit- wise negation of its corre- sponding character in the original string. 2.6.8 Increment/Decrement Operators Increment/decrement operators are unique in the sense that they operate only on variables and not on any value. The reason for this is that in addition to calculating the result value, the value of the variable itself changes as well. Operator Name Effect on $var Value of the Expression $var++ Post-increment $var is incre- The previous value mented by 1. of $var. ++$var Pre-increment $var is incre- The new value of mented by 1. $var (incremented by 1). $var-- Post-decrement $var is decre- The previous value mented by 1. of $var. --$var Pre-decrement $var is decre- The new value mented by 1. of $var (decre- mented by 1). As you can see from the previous table, there's a difference in the value of post- and pre-increment. However, in both cases, $var is incremented by 1. The only difference is in the value to which the increment expression evaluates. Example 1: $num1 = 5; $num2 = $num1++;// post-increment, $num2 is assigned $num1's original value print $num1; // this will print the value of $num1, which is now 6 print $num2; // this will print the value of $num2, which is the original value of $num1, thus, 5
Example 2: $num1 = 5; $num2 = ++$num1;// pre-increment, $num2 is assigned $num1's incremented value print $num1; // this will print the value of $num1, which is now 6 print $num2; // this will print the value of $num2, which is the same as the value of $num1, thus, 6 The same rules apply to pre- and post-decrement. 2.6.8.1 Incrementing Strings Strings (when not numeric) are incremented in a similar way to Perl. If the last letter is alphanumeric, it is incremented by 1. If it was `z', `Z', or `9', it is incremented to `a', `A', or `0' respectively, and the next alphanumeric is also incremented in the same way. If there is no next alphanumeric, one is added to the beginning of the string as `a', `A', and `1,' respectively. If this gives you a headache, just try and play around with it. You'll get the hang of it pretty quickly. Note: Non-numeric strings cannot be decremented. 2.6.9 The Cast Operators PHP provides a C-like way to force a type conversion of a value by using the cast operators. The operand appears on the right side of the cast operator, and its result is the converted type according to the following table. Operator Changes Type To (int), (integer) Integer (float), (real), (double) Floating point (string) String (bool), (boolean) Boolean (array) Array (object) Object The casting operators change the type of a value and not the type of a variable. For example: $str = "5"; $num = (int) $str; This results in $num being assigned the integer value of $str (5), but $str remains of type string.
2.6.10 The Silence Operator The operator @ silences error messages during the evaluation process of an expression. It is discussed in more detail in Chapter 7. 2.6.11 The One and Only Ternary Operator One of the most elegant operators is the ?: (question mark) operator. Its for- mat is truth_expr ? expr1 : expr2 The operator evaluates truth_expr and checks whether it is true. If it is, the value of the expression evaluates to the value of expr1 (expr2 is not evalu- ated). If it is false, the value of the expression evaluates to the value of expr2 (expr1 is not evaluated). For example, the following code snippet checks whether $a is set (using isset()) and displays a message accordingly: $a = 99; $message = isset($a) ? '$a is set' : '$a is not set'; print $message; This example prints the following: $a is set 2.7 CONTROL STRUCTURES PHP supports a variety of the most common control structures available in other programming languages. They can be basically divided into two groups: conditional control structures and loop control structures. The condi- tional control structures affect the flow of the program and execute or skip cer- tain code according to certain criteria, whereas loop control structures execute certain code an arbitrary number of times according to specified criteria. 2.7.1 Conditional Control Structures Conditional control structures are crucial in allowing your program to take different execution paths based on decisions it makes at runtime. PHP sup- ports both the if and switch conditional control structures.
2.7.1.1 if Statements Statement Statement List if (expr) if (expr): statement statement list elseif (expr) elseif (expr): statement statement list elseif (expr) elseif (expr): statement statement list ... ... else else: statement statement list endif; if statements are the most common conditional constructs, and they exist in most programming languages. The expression in the if statement is referred to as the truth expression. If the truth expression evaluates to true, the statement or statement list following it are executed; otherwise, they're not. You can add an else branch to an if statement to execute code only if all the truth expressions in the if statement evaluated to false: if ($var >= 50) { print '$var is in range'; } else { print '$var is invalid'; } Notice the braces that delimit the statements following if and else, which make these statements a statement block. In this particular case, you can omit the braces because both blocks contain only one statement in them. It is good practice to write these braces even if they're not syntactically required. Doing so improves readability, and it's easier to add more state- ments to the if block later (for example, during debugging). The elseif construct can be used to conduct a series of conditional checks and only execute the code following the first condition that is met. For example: if ($num < 0) { print '$num is negative'; } elseif ($num == 0) { print '$num is zero'; } elseif ($num > 0) { print '$num is positive'; }
2.7 Control Structures
The last elseif could be substituted with an else because, if $num is not negative and not zero, it must be positive. Note: It's common practice by PHP developers to use C-style else if nota- tion instead of elseif. Both styles of the if construct behave in the same way. While the state- ment style is probably more readable and convenient for use inside PHP code blocks, the statement list style extends readability when used to conditionally display HTML blocks. Here's an alternative way to implement the previous example using HTML blocks instead of print: <?php if ($num < 0): ?> <h1>$num is negative</h1> <?php elseif($num == 0): ?> <h1>$num is zero</h1> <?php elseif($num > 0): ?> <h1>$num is positive</h1> <?php endif; ?> As you can see, HTML blocks can be used just like any other statement. Here, only one of the HTML blocks are displayed, depending on the value of $num. Note: No variable substitution is performed in the HTML blocks. They are always printed as is. 2.7.1.2 switch Statements Statement Statement List switch (expr){ switch (expr): case expr: case expr: statement list statement list case expr: case expr: statement list statement list ... ... default: default: statement list statement list } endswitch; You can use the switch construct to elegantly replace certain lengthy if/ elseif constructs. It is given an expression and compares it to all possible case expressions listed in its body. When there's a successful match, the following code is executed, ignoring any further case lines (execution does not stop when the next case is reached). The match is done internally using the regular equality operator (==), not the identical operator (===). You can use the break statement to end execution and skip to the code following the switch construct.
Usually, break statements appear at the end of a case statement list, although it is not mandatory. If no case expression is met and the switch construct con- tains default, the default statement list is executed. Note that the default case must appear last in the list of cases or not appear at all: switch ($answer) { case 'y': case 'Y': print "The answer was yesn"; break; case 'n': case 'N': print "The answer was non"; break; default: print "Error: $answer is not a valid answern"; break; } 2.7.2 Loop Control Structures Loop control structures are used for repeating certain tasks in your program, such as iterating over a database query result set.
2.7.2.1 while loops Statement Statement List while (expr) while (expr): statement statement list endwhile; while loops are the simplest kind of loops. In the beginning of each iter- ation, the while's truth expression is evaluated. If it evaluates to true, the loop keeps on running and the statements inside it are executed. If it evalu- ates to false, the loop ends and the statement(s) inside the loop is skipped. For example, here's one possible implementation of factorial, using a while loop (assuming $n contains the number for which we want to calculate the facto- rial): $result = 1; while ($n > 0) { $result *= $n--; } print "The result is $result";
2.7.2.2 Loop Control: break and continue break; break expr; continue; continue expr; Sometimes, you want to terminate the execution of a loop in the middle of an iteration. For this purpose, PHP provides the break statement. If break appears alone, as in break; the innermost loop is stopped. break accepts an optional argument of the amount of nesting levels to break out of, break n; which will break from the n innermost loops (break 1; is identical to break;). n can be any valid expression. In other cases, you may want to stop the execution of a specific loop itera- tion and begin executing the next one. Complimentary to break, continue pro- vides this functionality. continue alone stops the execution of the innermost loop iteration and continues executing the next iteration of that loop. continue n can be used to stop execution of the n innermost loop iterations. PHP goes on executing the next iteration of the outermost loop. As the switch statement also supports break, it is counted as a loop when you want to break out of a series of loops with break n. 2.7.2.3 do...while Loops do statement while (expr); The do...while loop is similar to the previous while loop, except that the truth expression is checked at the end of each iteration instead of at the begin- ning. This means that the loop always runs at least once. do...while loops are often used as an elegant solution for easily breaking out of a code block if a certain condition is met. Consider the following example: do { statement list if ($error) { break; } statement list } while (false); Because do...while loops always iterate at least one time, the statements inside the loop are executed once, and only once. The truth expression is always false. However, inside the loop body, you can use the break statement to stop the execution of the statements at any point, which is convenient. Of course, do...while loops are also often used for regular iterating purposes. 2.7.2.4 for Loops Statement Statement List for (expr, expr, ...; expr, expr, ...; expr, expr, ...) for (expr, expr, ...; expr, expr, ...; expr, expr, ...): statement statement list endfor; PHP provides C-style for loops. The for loop accepts three arguments: for (start_expressions; truth_expressions; increment_expressions) Most commonly, for loops are used with only one expression for each of the start, truth, and increment expressions, which would make the previous syntax table look slightly more familiar. Statement Statement List for (expr; expr; expr) for (expr; expr; expr): statement statement list endfor; The start expression is evaluated only once when the loop is reached. Usually it is used to initialize the loop control variable. The truth expression is evaluated in the beginning of every loop iteration. If true, the statements inside the loop will be executed; if false, the loop ends. The increment expres- sion is evaluated at the end of every iteration before the truth expression is evaluated. Usually, it is used to increment the loop control variable, but it can be used for any other purpose as well. Both break and continue behave the same way as they do with while loops. continue causes evaluation of the incre- ment expression before it re-evaluates the truth expression.
2.7 Control Structures Here's an example: for ($i = 0; $i < 10; $i++) { print "The square of $i is " . $i*$i . "n"; } The result of running this code is The square of 0 is 0 The square of 1 is 1 ... The square of 9 is 81 Like in C, it is possible to supply more than one expression for each of the three arguments by using commas to delimit them. The value of each argu- ment is the value of the rightmost expression. Alternatively, it is also possible not to supply an expression with one or more of the arguments. The value of such an empty argument will be true. For example, the following is an infinite loop: for (;;) { print "I'm infiniten"; } Tip: PHP doesn't know how to optimize many kinds of loop invariants. For example, in the following for loop, count($array) will not be optimized to run only once. for ($i = 0; $i <= count($array); $i++) { } It should be rewritten as $count = count($array); for ($i = 0; $i <= $count; $i++) { } This ensures that you get the best performance during the execution of the loop.
2.7.3 Code Inclusion Control Structures Code inclusion control structures are crucial for organizing a program's source code. Not only will they allow you to structure your program into building blocks, but you will probably find that some of these building blocks can later be reused in other programs. 2.7.3.1 include Statement and Friends As in other languages, PHP allows for splitting source code into multiple files using the include statement. Split- ting your code into many files is usually helpful for code reuse (being able to include the same source code from various scripts) or just in helping keep the code more maintainable. When an include statement is executed, PHP reads the file, compiles it into intermediate code, and then executes the included code. Unlike C/C++, the include statement behaves somewhat like a function (although it isn't a function but a built-in language construct) and can return a value using the return statement. Also, the included file runs in the same variable scope as the including script (except for the execution of included functions which run with their their own variable scope). The prototype of include is include file_name; Here are two examples for using include: error_codes.php <?php $MY_OK = 0; $MY_ERROR = 1; ?> test.php <?php include "error_codes.php"; print ('The value of $MY_OK is ' . "$MY_OKn"); ?> This prints as The value of $MY_OK is 0
You can use both relative and absolute paths as the file name. Many developers like using absolute path names and create it by concatenating the server's document root and the relative path name. This allows them great flexibility when moving their PHP application among different servers and PHP installations. For example: include $_SERVER["DOCUMENT_ROOT"] . "/myscript.php"; In addition, if the INI directive, allow_url_fopen, is enabled in your PHP configuration (the default), you can also include URLs. This method is not rec- ommended for performance reasons because PHP must first download the source code to be included before it runs it. So, use this option only when it's really necessary. Here's an example: include "http://www.example.org/example.php"; The included URL must return a valid PHP script and not a web page which is HTML (possibly created by PHP). You can also use other protocols besides HTTP, such as FTP. When the included file or URL doesn't exist, include emits a PHP warn- ing but does not halt execution. If you want PHP to error out in such a case (usually, this is a fatal condition, so that's what you'd probably want), you can use the require statement, which is otherwise identical to include. There are two additional variants of include/require, which are probably the most useful. include_once/require_once which behave exactly like their include/require counterparts, except that they "remember" what files have been included, and if you try and include_once/require_once the same file again, it is just ignored. This behavior is similar to the C workaround for not including the same header files more than once. For the C developers among you, here's pretty much the require_once equivalent in C: my_header.h: #ifndef MY_HEADER_H #define MY_HEADER_H 1 ... /* The file's code */ #endif 2.7.3.2 eval() eval() is similar to include, but instead of compiling and executing code that comes from a file, it accepts the code as a string. This can be useful for running dynamically created code or retrieving code from an external data source manually (for example, a database) and then executing it. As the use of eval() is much less efficient than writing the code as part of your PHP code, we encourage you not to use it unless you can't do without: $str = '$var = 5;'; eval($str); print $var; This prints as 5 Tip: Variables that are based on user input should never be directly passed to eval() because this might allow the user to execute arbitrary code. 2.8 FUNCTIONS A function in PHP can be built-in or user-defined; however, they are both called the same way. The general form of a function call is func(arg1,arg2,...) The number of arguments varies from one function to another. Each argument can be any valid expression, including other function calls. Here is a simple example of a predefined function: $length = strlen("John"); strlen is a standard PHP function that returns the length of a string. Therefore, $length is assigned the length of the string "John": four. Here's an example of a function call being used as a function argument: $length = strlen(strlen("John")); You probably already guessed the result of this example. First, the inner strlen("John") is executed, which results in the integer 4. So, the code simpli- fies to $length = strlen(4); strlen() expects a string, and therefore (due to PHP's magical auto- conversion between types) converts the integer 4 to the string "4", and thus, the resulting value of $length is 1, the length of "4".