Control Structures Any PHP script is built out of a series of statements. A statement can be an assignment, a function call, a loop, a conditional statement of even a statement that does nothing (an empty statement). Statements usually end with a semicolon. In addition, statements can be grouped into a statement-group by encapsulating a group of statements with curly braces. A statement-group is a statement by itself as well. The various statement types are described in this chapter. <literal>if</literal> The if construct is one of the most important features of many languages, PHP included. It allows for conditional execution of code fragments. PHP features an if structure that is similar to that of C: ]]> As described in the section about expressions, expr is evaluated to its Boolean value. If expr evaluates to &true;, PHP will execute statement, and if it evaluates to &false; - it'll ignore it. More information about what values evaluate to &false; can be found in the 'Converting to boolean' section. The following example would display a is bigger than b if $a is bigger than $b: $b) echo "a is bigger than b"; ?> ]]> Often you'd want to have more than one statement to be executed conditionally. Of course, there's no need to wrap each statement with an if clause. Instead, you can group several statements into a statement group. For example, this code would display a is bigger than b if $a is bigger than $b, and would then assign the value of $a into $b: $b) { echo "a is bigger than b"; $b = $a; } ?> ]]> If statements can be nested indefinitely within other if statements, which provides you with complete flexibility for conditional execution of the various parts of your program. <literal>else</literal> Often you'd want to execute a statement if a certain condition is met, and a different statement if the condition is not met. This is what else is for. else extends an if statement to execute a statement in case the expression in the if statement evaluates to &false;. For example, the following code would display a is bigger than b if $a is bigger than $b, and a is NOT bigger than b otherwise: $b) { echo "a is bigger than b"; } else { echo "a is NOT bigger than b"; } ?> ]]> The else statement is only executed if the if expression evaluated to &false;, and if there were any elseif expressions - only if they evaluated to &false; as well (see elseif). <literal>elseif</literal> elseif, as its name suggests, is a combination of if and else. Like else, it extends an if statement to execute a different statement in case the original if expression evaluates to &false;. However, unlike else, it will execute that alternative expression only if the elseif conditional expression evaluates to &true;. For example, the following code would display a is bigger than b, a equal to b or a is smaller than b: $b) { echo "a is bigger than b"; } elseif ($a == $b) { echo "a is equal to b"; } else { echo "a is smaller than b"; } ?> ]]> There may be several elseifs within the same if statement. The first elseif expression (if any) that evaluates to &true; would be executed. In PHP, you can also write 'else if' (in two words) and the behavior would be identical to the one of 'elseif' (in a single word). The syntactic meaning is slightly different (if you're familiar with C, this is the same behavior) but the bottom line is that both would result in exactly the same behavior. The elseif statement is only executed if the preceding if expression and any preceding elseif expressions evaluated to &false;, and the current elseif expression evaluated to &true;. Alternative syntax for control structures PHP offers an alternative syntax for some of its control structures; namely, if, while, for, foreach, and switch. In each case, the basic form of the alternate syntax is to change the opening brace to a colon (:) and the closing brace to endif;, endwhile;, endfor;, endforeach;, or endswitch;, respectively. A is equal to 5 ]]> In the above example, the HTML block "A is equal to 5" is nested within an if statement written in the alternative syntax. The HTML block would be displayed only if $a is equal to 5. The alternative syntax applies to else and elseif as well. The following is an if structure with elseif and else in the alternative format: ]]> See also while, for, and if for further examples. <literal>while</literal> while loops are the simplest type of loop in PHP. They behave just like their C counterparts. The basic form of a while statement is: The meaning of a while statement is simple. It tells PHP to execute the nested statement(s) repeatedly, as long as the while expression evaluates to &true;. The value of the expression is checked each time at the beginning of the loop, so even if this value changes during the execution of the nested statement(s), execution will not stop until the end of the iteration (each time PHP runs the statements in the loop is one iteration). Sometimes, if the while expression evaluates to &false; from the very beginning, the nested statement(s) won't even be run once. Like with the if statement, you can group multiple statements within the same while loop by surrounding a group of statements with curly braces, or by using the alternate syntax: The following examples are identical, and both print numbers from 1 to 10: ]]> <literal>do-while</literal> do-while loops are very similar to while loops, except the truth expression is checked at the end of each iteration instead of in the beginning. The main difference from regular while loops is that the first iteration of a do-while loop is guaranteed to run (the truth expression is only checked at the end of the iteration), whereas it's may not necessarily run with a regular while loop (the truth expression is checked at the beginning of each iteration, if it evaluates to &false; right from the beginning, the loop execution would end immediately). There is just one syntax for do-while loops: 0); ?> ]]> The above loop would run one time exactly, since after the first iteration, when truth expression is checked, it evaluates to &false; ($i is not bigger than 0) and the loop execution ends. Advanced C users may be familiar with a different usage of the do-while loop, to allow stopping execution in the middle of code blocks, by encapsulating them with do-while (0), and using the break statement. The following code fragment demonstrates this: ]]> Don't worry if you don't understand this right away or at all. You can code scripts and even powerful scripts without using this 'feature'. <literal>for</literal> for loops are the most complex loops in PHP. They behave like their C counterparts. The syntax of a for loop is: The first expression (expr1) is evaluated (executed) once unconditionally at the beginning of the loop. In the beginning of each iteration, expr2 is evaluated. If it evaluates to &true;, the loop continues and the nested statement(s) are executed. If it evaluates to &false;, the execution of the loop ends. At the end of each iteration, expr3 is evaluated (executed). Each of the expressions can be empty. expr2 being empty means the loop should be run indefinitely (PHP implicitly considers it as &true;, like C). This may not be as useless as you might think, since often you'd want to end the loop using a conditional break statement instead of using the for truth expression. Consider the following examples. All of them display numbers from 1 to 10: 10) { break; } echo $i; } /* example 3 */ $i = 1; for (; ; ) { if ($i > 10) { break; } echo $i; $i++; } /* example 4 */ for ($i = 1; $i <= 10; print $i, $i++); ?> ]]> Of course, the first example appears to be the nicest one (or perhaps the fourth), but you may find that being able to use empty expressions in for loops comes in handy in many occasions. PHP also supports the alternate "colon syntax" for for loops. <literal>foreach</literal> PHP 4 introduced a foreach construct, much like Perl and some other languages. This simply gives an easy way to iterate over arrays. foreach works only on arrays, and will issue an error when you try to use it on a variable with a different data type or an uninitialized variable. There are two syntaxes; the second is a minor but useful extension of the first: $value) statement ]]> The first form loops over the array given by array_expression. On each loop, the value of the current element is assigned to $value and the internal array pointer is advanced by one (so on the next loop, you'll be looking at the next element). The second form does the same thing, except that the current element's key will be assigned to the variable $key on each loop. When foreach first starts executing, the internal array pointer is automatically reset to the first element of the array. This means that you do not need to call reset before a foreach loop. Also note that foreach operates on a copy of the specified array and not the array itself. Therefore, the array pointer is not modified as with the each construct, and changes to the array element returned are not reflected in the original array. However, the internal pointer of the original array is advanced with the processing of the array. Assuming the foreach loop runs to completion, the array's internal pointer will be at the end of the array. As of PHP 5, you can easily modify array's elements by preceding $value with &. This will assign reference instead of copying the value. ]]> This is possible only if iterated array can be referenced (i.e. is variable). foreach does not support the ability to suppress error messages using '@'. You may have noticed that the following are functionally identical: \n"; } foreach ($arr as $value) { echo "Value: $value
\n"; } ?> ]]>
The following are also functionally identical: \n"; } foreach ($arr as $key => $value) { echo "Key: $key; Value: $value
\n"; } ?> ]]>
Some more examples to demonstrate usages: $v.\n"; $i++; } /* foreach example 3: key and value */ $a = array( "one" => 1, "two" => 2, "three" => 3, "seventeen" => 17 ); foreach ($a as $k => $v) { echo "\$a[$k] => $v.\n"; } /* foreach example 4: multi-dimensional arrays */ $a = array(); $a[0][0] = "a"; $a[0][1] = "b"; $a[1][0] = "y"; $a[1][1] = "z"; foreach ($a as $v1) { foreach ($v1 as $v2) { echo "$v2\n"; } } /* foreach example 5: dynamic arrays */ foreach (array(1, 2, 3, 4, 5) as $v) { echo "$v\n"; } ?> ]]>
<literal>break</literal> break ends execution of the current for, foreach, while, do-while or switch structure. break accepts an optional numeric argument which tells it how many nested enclosing structures are to be broken out of. \n"; } /* Using the optional argument. */ $i = 0; while (++$i) { switch ($i) { case 5: echo "At 5
\n"; break 1; /* Exit only the switch. */ case 10: echo "At 10; quitting
\n"; break 2; /* Exit the switch and the while. */ default: break; } } ?> ]]>
<literal>continue</literal> continue is used within looping structures to skip the rest of the current loop iteration and continue execution at the beginning of the next iteration. Note that in PHP the switch statement is considered a looping structure for the purposes of continue. continue accepts an optional numeric argument which tells it how many levels of enclosing loops it should skip to the end of. \n"; while (1) { echo "  Middle
\n"; while (1) { echo "  Inner
\n"; continue 3; } echo "This never gets output.
\n"; } echo "Neither does this.
\n"; } ?> ]]>
Omitting the semicolon after continue can lead to confusion. Here's an example of what you shouldn't do. ]]> One can expect the result to be : but this script will output : because the return value of the print call is int(1), and it will look like the optional numeric argument mentioned above.
<literal>switch</literal> The switch statement is similar to a series of IF statements on the same expression. In many occasions, you may want to compare the same variable (or expression) with many different values, and execute a different piece of code depending on which value it equals to. This is exactly what the switch statement is for. Note that unlike some other languages, the continue statement applies to switch and acts similar to break. If you have a switch inside a loop and wish to continue to the next iteration of the outer loop, use continue 2. The following two examples are two different ways to write the same thing, one using a series of if and elseif statements, and the other using the switch statement: <literal>switch</literal> structure ]]> <literal>switch</literal> structure allows usage of strings ]]> It is important to understand how the switch statement is executed in order to avoid mistakes. The switch statement executes line by line (actually, statement by statement). In the beginning, no code is executed. Only when a case statement is found with a value that matches the value of the switch expression does PHP begin to execute the statements. PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement. If you don't write a break statement at the end of a case's statement list, PHP will go on executing the statements of the following case. For example: ]]> Here, if $i is equal to 0, PHP would execute all of the echo statements! If $i is equal to 1, PHP would execute the last two echo statements. You would get the expected behavior ('i equals 2' would be displayed) only if $i is equal to 2. Thus, it is important not to forget break statements (even though you may want to avoid supplying them on purpose under certain circumstances). In a switch statement, the condition is evaluated only once and the result is compared to each case statement. In an elseif statement, the condition is evaluated again. If your condition is more complicated than a simple compare and/or is in a tight loop, a switch may be faster. The statement list for a case can also be empty, which simply passes control into the statement list for the next case. ]]> A special case is the default case. This case matches anything that wasn't matched by the other cases, and should be the last case statement. For example: ]]> The case expression may be any expression that evaluates to a simple type, that is, integer or floating-point numbers and strings. Arrays or objects cannot be used here unless they are dereferenced to a simple type. The alternative syntax for control structures is supported with switches. For more information, see Alternative syntax for control structures . ]]> <literal>declare</literal> The declare construct is used to set execution directives for a block of code. The syntax of declare is similar to the syntax of other flow control constructs: The directive section allows the behavior of the declare block to be set. Currently only one directive is recognized: the ticks directive. (See below for more information on the ticks directive) The statement part of the declare block will be executed -- how it is executed and what side effects occur during execution may depend on the directive set in the directive block. The declare construct can also be used in the global scope, affecting all code following it. ]]> Ticks A tick is an event that occurs for every N low-level statements executed by the parser within the declare block. The value for N is specified using ticks=N within the declare blocks's directive section. The event(s) that occur on each tick are specified using the register_tick_function. See the example below for more details. Note that more than one event can occur for each tick. Profile a section of PHP code ;"; } } // Display the data stored in the profiler print_r(profile(TRUE)); ?> ]]> The example profiles the PHP code within the 'declare' block, recording the time at which every second low-level statement in the block was executed. This information can then be used to find the slow areas within particular segments of code. This process can be performed using other methods: using ticks is more convenient and easier to implement. Ticks are well suited for debugging, implementing simple multitasking, background I/O and many other tasks. See also register_tick_function and unregister_tick_function. return If called from within a function, the return statement immediately ends execution of the current function, and returns its argument as the value of the function call. return will also end the execution of an eval statement or script file. If called from the global scope, then execution of the current script file is ended. If the current script file was includeed or requireed, then control is passed back to the calling file. Furthermore, if the current script file was includeed, then the value given to return will be returned as the value of the include call. If return is called from within the main script file, then script execution ends. If the current script file was named by the auto_prepend_file or auto_append_file configuration options in &php.ini;, then that script file's execution is ended. For more information, see Returning values. Note that since return is a language construct and not a function, the parentheses surrounding its arguments are only required if the argument contains an expression. It is common to leave them out while returning a variable. <function>require</function> The require statement includes and evaluates the specific file. require includes and evaluates a specific file. Detailed information on how this inclusion works is described in the documentation for include. require and include are identical in every way except how they handle failure. include produces a Warning while require results in a Fatal Error. In other words, don't hesitate to use require if you want a missing file to halt processing of the page. include does not behave this way, the script will continue regardless. Be sure to have an appropriate include_path setting as well. Basic <function>require</function> examples ]]> See the include documentation for more examples. Prior to PHP 4.0.2, the following applies: require will always attempt to read the target file, even if the line it's on never executes. The conditional statement won't affect require. However, if the line on which the require occurs is not executed, neither will any of the code in the target file be executed. Similarly, looping structures do not affect the behaviour of require. Although the code contained in the target file is still subject to the loop, the require itself happens only once. ¬e.language-construct; &warn.no-win32-fopen-wrapper; See also include, require_once, include_once, eval, file, readfile, virtual and include_path. <function>include</function> The include statement includes and evaluates the specified file. The documentation below also applies to require. The two constructs are identical in every way except how they handle failure. include produces a Warning while require results in a Fatal Error. In other words, use require if you want a missing file to halt processing of the page. include does not behave this way, the script will continue regardless. Be sure to have an appropriate include_path setting as well. Be warned that parse error in required file doesn't cause processing halting. Files for including are first looked in include_path relative to the current working directory and then in include_path relative to the directory of current script. E.g. if your include_path is ., current working directory is /www/, you included include/a.php and there is include "b.php" in that file, b.php is first looked in /www/ and then in /www/include/. If filename begins with ../, it is looked only in include_path relative to the current working directory. When a file is included, the code it contains inherits the variable scope of the line on which the include occurs. Any variables available at that line in the calling file will be available within the called file, from that point forward. Basic <function>include</function> example test.php ]]> If the include occurs inside a function within the calling file, then all of the code contained in the called file will behave as though it had been defined inside that function. So, it will follow the variable scope of that function. Including within functions ]]> When a file is included, parsing drops out of PHP mode and into HTML mode at the beginning of the target file, and resumes again at the end. For this reason, any code inside the target file which should be executed as PHP code must be enclosed within valid PHP start and end tags. If "URL fopen wrappers" are enabled in PHP (which they are in the default configuration), you can specify the file to be included using a URL (via HTTP or other supported wrapper - see for a list of protocols) instead of a local pathname. If the target server interprets the target file as PHP code, variables may be passed to the included file using a URL request string as used with HTTP GET. This is not strictly speaking the same thing as including the file and having it inherit the parent file's variable scope; the script is actually being run on the remote server and the result is then being included into the local script. &warn.no-win32-fopen-wrapper; <function>include</function> through HTTP ]]> See also Remote files, fopen and file for related information. Because include and require are special language constructs, you must enclose them within a statement block if it's inside a conditional block. include() and conditional blocks ]]> Handling Returns: It is possible to execute a return statement inside an included file in order to terminate processing in that file and return to the script which called it. Also, it's possible to return values from included files. You can take the value of the include call as you would a normal function. This is not, however, possible when including remote files unless the output of the remote file has valid PHP start and end tags (as with any local file). You can declare the needed variables within those tags and they will be introduced at whichever point the file was included. Because include is a special language construct, parentheses are not needed around its argument. Take care when comparing return value. Comparing return value of include ]]> In PHP 3, the return may not appear inside a block unless it's a function block, in which case the return applies to that function and not the whole file. <function>include</function> and the <function>return</function> statement noreturn.php testreturns.php ]]> $bar is the value 1 because the include was successful. Notice the difference between the above examples. The first uses return within the included file while the other does not. If the file can't be included, &false; is returned and E_WARNING is issued. If there are functions defined in the included file, they can be used in the main file independent if they are before return or after. If the file is included twice, PHP 5 issues fatal error because functions were already declared, while PHP 4 doesn't complain about functions defined after return. It is recommended to use include_once instead of checking if the file was already included and conditionally return inside the included file. A few other ways to "include" files into variables are with fopen, file or by using include along with Output Control Functions. ¬e.language-construct; See also require, require_once, include_once, readfile, virtual, and include_path. <function>require_once</function> The require_once statement includes and evaluates the specified file during the execution of the script. This is a behavior similar to the require statement, with the only difference being that if the code from a file has already been included, it will not be included again. See the documentation for require for more information on how this statement works. require_once should be used in cases where the same file might be included and evaluated more than once during a particular execution of a script, and you want to be sure that it is included exactly once to avoid problems with function redefinitions, variable value reassignments, etc. For examples on using require_once and include_once, look at the PEAR code included in the latest PHP source code distributions. Return values are the same as with include. If the file was already included, this function returns &true; require_once was added in PHP 4.0.1pl2 Be aware, that the behaviour of require_once and include_once may not be what you expect on a non case sensitive operating system (such as Windows). <function>require_once</function> is case insensitive on Windows ]]> This behaviour changed in PHP 5 - the path is normalized first so that C:\PROGRA~1\A.php is realized the same as C:\Program Files\a.php and the file is required just once. &warn.no-win32-fopen-wrapper; See also require, include, include_once, get_required_files, get_included_files, readfile, and virtual. <function>include_once</function> The include_once statement includes and evaluates the specified file during the execution of the script. This is a behavior similar to the include statement, with the only difference being that if the code from a file has already been included, it will not be included again. As the name suggests, it will be included just once. include_once should be used in cases where the same file might be included and evaluated more than once during a particular execution of a script, and you want to be sure that it is included exactly once to avoid problems with function redefinitions, variable value reassignments, etc. For more examples on using require_once and include_once, look at the PEAR code included in the latest PHP source code distributions. Return values are the same as with include. If the file was already included, this function returns &true; include_once was added in PHP 4.0.1pl2 Be aware, that the behaviour of include_once and require_once may not be what you expect on a non case sensitive operating system (such as Windows). <function>include_once</function> is case insensitive on Windows ]]> This behaviour changed in PHP 5 - the path is normalized first so that C:\PROGRA~1\A.php is realized the same as C:\Program Files\a.php and the file is included just once. &warn.no-win32-fopen-wrapper; See also include, require, require_once, get_required_files, get_included_files, readfile, and virtual.