if 结构是很多语言包括 PHP 在内最重要的特性之一,它允许按照条件执行代码片段。
if 语句可以无限层地嵌套在其它 if 语句中,这给程序的不同部分的条件执行提供了充分的弹性。
else 延伸了 if 语句,可以在 if 语句中的表达式的值为 FALSE 时执行语句。
elseif,在 elseif 的条件表达式值为 TRUE 时执行语句。
在同一个 if 结构中可以有多个 elseif 语句。第一个表达式值为 TRUE 的 elseif 语句(如果有的话)将会执行。在 PHP 中,也可以写成“else if”(两个单词),它和“elseif”(一个单词)的行为完全一样。句法分析的含义有少许区别(如果你熟悉 C 语言的话,这是同样的行为),但是底线是两者会产生完全一样的行为。
Note: 必须要注意的是 elseif 与 else if 只有在类似上例中使用大括号的情况下才认为是完全相同
PHP 提供了一些流程控制的替代语法,包括 if,while,for,foreach 和 switch。替代语法的基本形式是把左花括号({)换成冒号(:),把右花括号(})分别换成endif;,endwhile;,endfor;,endforeach; 以及 endswitch;。 替代语法同样可以用在 else 和 elseif 中。
while 循环是 PHP 中最简单的循环类型。
和 if 语句一样,可以在 while 循环中用花括号括起一个语句组,或者用替代语法。
do-while 和 while 循环非常相似,区别在于表达式的值是在每次循环结束时检查而不是开始时。
for 循环是 PHP 中最复杂的循环结构。
每个表达式都可以为空或包括逗号分隔的多个表达式。
PHP 4 引入了 foreach 结构,是一种遍历数组简便方法。foreach 仅能用于数组。有两种语法,第二种比较次要但却是第一种的有用的扩展。
foreach (array_expression as $value) statement foreach (array_expression as $key => $value) statement
第一种格式遍历给定的 array_expression 数组。每次循环中,当前单元的值被赋给 $value并且数组内部的指针向前移一步(因此下一次循环中将会得到下一个单元)。
第二种格式做同样的事,只除了当前单元的键名也会在每次循环中被赋给变量 $key。
自PHP 5 起,还可能遍历对象。
Note:当 foreach 开始执行时,数组内部的指针会自动指向第一个单元。这意味着不需要在foreach 循环之前调用 reset()。
自 PHP 5 起,可以很容易地通过在 $value 之前加上 & 来修改数组的元素。此方法将以引用赋值而不是拷贝一个值。
1
2
3
4
5
6
7
|
<?php $arr
= array (1, 2, 3, 4);
foreach
( $arr
as & $value ) {
$value
= $value
* 2;
} // $arr is now array(2, 4, 6, 8) ?> |
break 结束当前 for,foreach,while,do-while 或者 switch 结构的执行。
break 可以接受一个可选的数字参数来决定跳出几重循环。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<?php $arr
= array ( ‘one‘ , ‘two‘ , ‘three‘ , ‘four‘ , ‘stop‘ , ‘five‘ );
while
(list (, $val ) = each( $arr )) {
if
( $val
== ‘stop‘ ) {
break ; /* You could also write ‘break 1;‘ here. */
}
echo
"$val<br /> " ;
} /* 使用可选参数 */ $i
= 0;
while
(++ $i ) {
switch
( $i ) {
case
5:
echo
"At 5<br /> " ;
break
1; /* 只退出 switch. */
case
10:
echo
"At 10; quitting<br /> " ;
break
2; /* 退出 switch 和 while 循环 */
default :
break ;
}
} ?> |
continue 在循环结构用用来跳过本次循环中剩余的代码并在条件求值为真时开始执行下一次循环
continue 接受一个可选的数字参数来决定跳过几重循环到循环结尾。
1 <?php 2 while (list ($key, $value) = each($arr)) { 3 if (!($key % 2)) { // skip odd members 4 continue; 5 } 6 do_something_odd($value); 7 } 8 9 $i = 0; 10 while ($i++ < 5) { 11 echo "Outer<br /> "; 12 while (1) { 13 echo " Middle<br /> "; 14 while (1) { 15 echo " Inner<br /> "; 16 continue 3; 17 } 18 echo "This never gets output.<br /> "; 19 } 20 echo "Neither does this.<br /> "; 21 } 22 ?>
省略 continue 后面的分号会导致混淆。
switch 语句和具有同样表达式的一系列的 IF 语句相似,即把同一个变量(或表达式)与很多不同的值比较,并根据它等于哪个值来执行不同的代码。
Note: continue 语句作用到 switch 上的作用类似于 break。如果在循环中有一个 switch 并希望 continue 到外层循环中的下一个轮回,用 continue 2。
理解 switch 是怎样执行的非常重要。switch 语句一行接一行地执行(实际上是语句接语句)。开始时没有代码被执行。仅当一个 case 语句中的值和 switch 表达式的值匹配时 PHP 才开始执行语句,直到 switch 的程序段结束或者遇到第一个 break 语句为止。如果不在 case 的语句段最后写上 break 的话,PHP 将继续执行下一个 case 中的语句段。
在 switch 语句中条件只求值一次并用来和每个 case 语句比较。在 elseif 语句中条件会再次求值。如果条件比一个简单的比较要复杂得多或者在一个很多次的循环中,那么用 switch 语句可能会快一些。
在一个 case 中的语句也可以为空,这样只不过将控制转移到了下一个 case 中的语句。
<?php switch ($i) { case 0: case 1: case 2: echo "i is less than 3 but not negative"; break; case 3: echo "i is 3"; } ?>
一个 case 的特例是 default。它匹配了任何和其它 case 都不匹配的情况。
case 表达式可以是任何求值为简单类型的表达式,即整型或浮点数以及字符串。不能用数组或对象,除非它们被解除引用成为简单类型。
switch 支持替代语法的流程控制。
允许使用分号(;)代替case语句后的冒号(:),
declare 结构用来设定一段代码的执行指令。declare 的语法和其它流程控制结构相似:
declare (directive) statement
directive 部分允许设定 declare 代码段的行为。目前只认识两个指令:ticks 指令以及 encoding指令。
Note: encoding 是 PHP 5.3.0 新增指令。
declare 代码段中的 statement 部分将被执行——怎样执行以及执行中有什么副作用出现取决于 directive 中设定的指令。
declare 结构也可用于全局范围,影响到其后的所有代码(但如果有 declare 结构的文件被其它文件包含,它对包含它的文件不起作用)。
<?php // you can use this: declare(ticks=1) { // entire script here } // or you can use this: declare(ticks=1); // entire script here ?>
Ticks
ticks 指令在 PHP 5.3.0 中是过时指令,将会从 PHP 6.0.0 移除。
Tick 是一个在 declare 代码段中解释器每执行 N 条低级语句就会发生的事件。N 的值是在declare 中的 directive 部分用 ticks=N
来指定的。
在每个 tick 中出现的事件是由 register_tick_function() 来指定的。
Ticks 很适合用来做调试,以及实现简单的多任务,后台 I/O 和很多其它任务。
在一个函数中调用 return() 语句,将立即结束此函数的执行并将它的参数作为函数的值返回。return() 也会终止 eval() 语句或者脚本文件的执行。
如果在全局范围中调用,则当前脚本文件中止运行。如果当前脚本文件是被 include() 的或者require() 的,则控制交回调用文件。此外,如果当前脚本是被 include() 的,则 return()的值会被当作 include() 调用的返回值。如果在主脚本文件中调用 return(),则脚本中止运行。如果当前脚本文件是在 php.ini 中的配置选项 auto_prepend_file 或者 auto_append_file 所指定的,则此脚本文件中止运行。
Note: 注意既然 return() 是语言结构而不是函数,因此其参数没有必要用括号将其括起来。通常都不用括号,实际上也应该不用,这样可以降低 PHP 的负担。
require() 语句包含并运行指定文件,详见 include() 文档。
require() 和 include() 几乎完全一样,除了处理失败的方式不同之外。include() 产生一个Warning而 require() 则导致一个 Fatal Error。换句话说,如果想在丢失文件时停止处理页面,那就别犹豫了,用 require() 吧。include() 就不是这样,脚本会继续运行。同时也要确认设置了合适的include_path。
1 <?php 2 3 require ‘prepend.php‘; 4 5 require $somefile; 6 7 require (‘somefile.txt‘); 8 9 ?>
include() 语句包含并运行指定文件。
以下文档也适用于 require()。这两种结构除了在如何处理失败之外完全一样。include() 产生一个警告而 require() 则导致一个致命错误。换句话说,如果想在遇到丢失文件时停止处理页面就用 require()。include() 就不是这样,脚本会继续运行。同时也要确认设置了合适的
include_path。
当一个文件被包含时,其中所包含的代码继承了 include 所在行的变量范围。从该处开始,调用文件在该行处可用的任何变量在被调用的文件中也都可用。不过所有在包含文件中定义的函数和类都具有全局作用域。
1 vars.php 2 <?php 3 4 $color = ‘green‘; 5 $fruit = ‘apple‘; 6 7 ?> 8 9 test.php 10 <?php 11 12 echo "A $color $fruit"; // A 13 14 include ‘vars.php‘; 15 16 echo "A $color $fruit"; // A green apple 17 18 ?>
如果 include 出现于调用文件中的一个函数里,则被调用的文件中所包含的所有代码将表现得如同它们是在该函数内部定义的一样。所以它将遵循该函数的变量范围。
include() 是一个特殊的语言结构,其参数不需要括号。在比较其返回值时要注意。
比较 include 的返回值
<?php
// won‘t work, evaluated as include((‘vars.php‘) == ‘OK‘), i.e. include(‘‘)
if (include(‘vars.php‘) == ‘OK‘) {
echo ‘OK‘;
}
// works
if ((include ‘vars.php‘) == ‘OK‘) {
echo ‘OK‘;
}
?>
include() 和 return() 语句
return.php
<?php
$var = ‘PHP‘;
return $var;
?>
noreturn.php
<?php
$var = ‘PHP‘;
?>
testreturns.php
<?php
$foo = include ‘return.php‘;
echo $foo; // prints ‘PHP‘
$bar = include ‘noreturn.php‘;
echo $bar; // prints 1
?>
$bar 的值为 1 是因为 include 成功运行了。注意以上例子中的区别。第一个在被包含的文件中用了 return() 而另一个没有。如果文件不能被包含,则返回 FALSE 并发出一个E_WARNING 警告。
如果在包含文件中定义有函数,这些函数可以独立于是否在 return() 之前还是之后在主文件中使用。推荐使用 include_once() 而不是检查文件是否已包含并在包含文件中有条件返回。
另一个将 PHP 文件“包含”到一个变量中的方法是用输出控制函数结合 include() 来捕获其输出,例如:
1 <?php 2 $string = get_include_contents(‘somefile.php‘); 3 4 function get_include_contents($filename) { 5 if (is_file($filename)) { 6 ob_start(); 7 include $filename; 8 $contents = ob_get_contents(); 9 ob_end_clean(); 10 return $contents; 11 } 12 return false; 13 } 14 15 ?>
要在脚本中自动包含文件,参见 php.ini 中的 auto_prepend_file 和 auto_append_file 配置选项。
Note: 因为是一个语言构造器而不是一个函数,不能被 可变函数 调用。
goto操作符可以用来跳转到程序中的某一指定位置。该目标位置可以用目标名称 加上冒号来标记。PHP中的goto有一定限制,只能在同一个文件和作用域中跳转, 也就是说你无法跳出一个函数或类方法,也无法跳入到另一个函数。你也无法跳入到任何循环或者switch 结构中。常见的用法是用来跳出循环或者switch,可以代替多层的break。
1 <?php 2 goto a; 3 echo ‘Foo‘; 4 5 a: 6 echo ‘Bar‘; 7 ?> 8 9 以上例程会输出:Bar