流程控制:中止语句
一个完整的脚本程序应该由一系列语句构成。一条语句也许是一个赋值语句、一个条件判断、一个循环、一个函数调用、或者是什么也不做的空语句。语句通常使用分号结束,并且多个语句可使用花括号进行分组,当做一行语句。
在之前的章节中我们已经学习了赋值语句,这章我们学习 PHP 的流程控制。
流程控制包括条件判断(if
、else
、elseif/else if
、switch
)、循环(while
、do-while
、for
、foreach
)和中止循环(break
、continue
、return
)等。
上一节我们学习了循环语句,下面我们来看看中止语句。
当一个循环未设置或者循环条件出错时,如果循环体内没有中止语句,那么该循环将一直运行,耗费系统资源直至被关闭或者服务器宕机。例如下面代码,如果放在服务器上运行,一段时间后你可能会看到Fatal error: Maximum execution time of 60 seconds exceeded
(执行时间超过最大执行时间)的错误提示:
<?php
for ($i=0; ; $i++) {
echo ' ';
}
这些是应该避免发生的!一段可能被循环执行的代码应该设置合理的中止条件来跳出循环。
在前两节的示例代码中,我们使用了break
语句来中止循环,这是一个中止语句,除此之外还有continue
、return
等。下面我们分别对它们进行讲解。
break
break
表示结束当前循环的执行,仅用于switch
、while
、do-while
、for
和foreach
结构。
其中switch
不属于循环结构,但因特殊性(如果把if
结构看做单选题,那么缺少break
的switch
结构就类似于连续多选题),经常需要break
来中断流程,故break
可用于switch
结构。
break
的使用示例如下:
<?php
// break
// switch结构
$choose = 3;
switch($choose) {
case 1:
echo '选项一';
// break;
case 2:
echo '选项二';
break;
case 3:
echo '选项三';
// break;
default:
echo '默认值';
}
// 输出:选项三默认值
// while结构:输出1~100的整数
$i = 1;
while (true) {
echo '已循环 ', $i, ' 次', PHP_EOL;
$i++;
// 设置循环条件
if($i > 100)
break;
}
// do-while结构:输出1~100的整数
$i = 1;
do {
echo '已循环 ', $i, ' 次', PHP_EOL;
$i++;
// 设置循环条件
if($i > 100)
break;
}while(true);
// for结构:输出1~100的整数
for ($i = 1; ; $i++) {
echo '已循环 ', $i, ' 次', PHP_EOL;
// 设置循环条件
if($i >= 100)
break;
}
// foreach结构:查找数组中值为“极速数据”的键值对
$arr = [
'name'=>'极速数据',
'host'=>'https://www.jisuapi.com/',
'column'=>'PHP教程'
];
foreach ($arr as $key => $value) {
if($value == '极速数据')
echo $key,': ',$value;
break;
}
// 输出:name: 极速数据
以上示例只有一重循环(即循环体内无第二个循环体),但若是多重循环(循环体内嵌套循环)呢?请看下面示例:
<?php
// 多重循环嵌套:查找一个二维数组中值为“极速数据”的键值对
$arr = [
['一个', '很随便', '的', '数组', '混进了', '听起来', '很高大上的', '二维数组', '我还故意加了一个值','极速数据','来检测多重循环'],
[1, 2, 3, 4, 5, 6, 7, 8],
[
'name'=>'极速数据',
'host'=>'https://www.jisuapi.com/',
'columns'=>['PHP教程', 'Python教程', 'HTML5教程', 'Javascript教程'],
'profile'=>'极速数据平台提供各类生活数据API,方便开发者快速简单的开发APP、软件及其他服务平台。公交、火车、违章、快递等数据应有尽有。',
'admin'=>'Liu',
'create'=>2011,
]
];
foreach ($arr as $key => $value) {
foreach ($value as $key2 => $value2) {
// if(is_array($value2)) {
// echo $key2,' : ',json_encode($value2), PHP_EOL;
// } else {
// echo $key2,' : ',$value2, PHP_EOL;
// }
if($value2 == '极速数据') {
echo $key2, ' : ', $value2, PHP_EOL;
break;
}
}
}
/* 输出:
9 : 极速数据
name : 极速数据
*/
以上示例代码中,break
只终止了最靠近它的循环。那么如果将需求改为“只检测第一次出现的'极速数据'键值对”呢?那么可以使用break
的可选参数来跳出指定的循环层次。示例代码如下:
<?php
// 使用了break接受数字参数决定跳出循环的层数
$arr = [
['一个', '很随便', '的', '数组', '混进了', '听起来', '很高大上的', '二维数组', '我还故意加了一个值','极速数据','来检测多重循环'],
[1, 2, 3, 4, 5, 6, 7, 8],
[
'name'=>'极速数据',
'host'=>'https://www.jisuapi.com/',
'columns'=>['PHP教程', 'Python教程', 'HTML5教程', 'Javascript教程'],
'profile'=>'极速数据平台提供各类生活数据API,方便开发者快速简单的开发APP、软件及其他服务平台。公交、火车、违章、快递等数据应有尽有。',
'admin'=>'Liu',
'create'=>2011,
]
];
foreach ($arr as $key => $value) {
foreach ($value as $key2 => $value2) {
if($value2 == '极速数据') {
echo $key2, ' : ', $value2, PHP_EOL;
break 2;// 跳出两层循环(从break所在的循环开始)
}
}
}
// 输出:9 : 极速数据
上面两段代码去掉注释的话几乎一样,除了在第二段代码中break
后跟了一个参数2
,它代表break
跳出自break所在的循环起的第二层循环。
需要注意的是,break
只接受整型数字参数或者干脆不接受参数(这代表只跳出一层循环,等同于break 1;
),而不接受变量(我们始终坚持使用最新稳定版本的 PHP(大于7.0
),而在 PHP 5.4 版本中取消了变量作为break
参数传递)。
continue
continue
与break
不同,break
在英文中是“打断”的意思,而continue
则是“继续”。实际上在 PHP 中这二者除了定义不同,使用上别无二致。请看下列示例:
<?php
// continue
$a = 0;
while ($a < 10) {
$a++;
if($a == 5)
continue;
echo $a , ' ';
}
/* 输出:(其中数字 5 不在其中)
1 2 3 4 6 7 8 9 10
*/
// break
$a = 0;
while ($a < 10) {
$a++;
if($a == 5)
break;
echo $a , ' ';
}
/* 输出:(从 5 开始不再输出)
1 2 3 4
*/
与break
跳出整层循环不同,continue
仅跳过符合中止条件的后面的代码。例如上面的例子,continue
只跳过了当$a == 5
条件成立时后面的echo $a , ' ';
代码,然后开始下一次的循环。
如果把break
比作“断尾求生”,那么continue
或许可以比作“蛇类的蜕皮”。同样是舍弃,break
要直接的多,continue
则属于“断断续续”。请看下方continue
在多重循环中的表现:
<?php
// continue 多重循环示例
$arr = [
['一个', '很随便', '的', '数组', '混进了', '听起来', '很高大上的', '二维数组', '我还故意加了一个值','极速数据','来检测多重循环', '还在同一数组添加了另一个相同的值', '极速数据', '来验证continue'],
[1, 2, 3, 4, 5, 6, 7, 8],
[
'name'=>'极速数据',
'host'=>'https://www.jisuapi.com/',
'columns'=>['PHP教程', 'Python教程', 'HTML5教程', 'Javascript教程'],
'profile'=>'极速数据平台提供各类生活数据API,方便开发者快速简单的开发APP、软件及其他服务平台。公交、火车、违章、快递等数据应有尽有。',
'admin'=>'Liu',
'create'=>2011,
'test'=>'极速数据'
]
];
foreach ($arr as $key => $value) {
foreach ($value as $key2 => $value2) {
if($value2 != '极速数据')
continue;
echo $key2, ' : ', $value2, PHP_EOL;
}
}
/* 输出:
9 : 极速数据
12 : 极速数据
name : 极速数据
test : 极速数据
*/
以上代码输出了二维数组中所有值为“极速数据”的键值对。那么对比一下break
?
<?php
$arr = [
['一个', '很随便', '的', '数组', '混进了', '听起来', '很高大上的', '二维数组', '我还故意加了一个值','极速数据','来检测多重循环', '还在同一数组添加了另一个相同的值', '极速数据', '来验证continue'],
[1, 2, 3, 4, 5, 6, 7, 8],
[
'name'=>'极速数据',// 试试将这行注释掉
'host'=>'https://www.jisuapi.com/',
'columns'=>['PHP教程', 'Python教程', 'HTML5教程', 'Javascript教程'],
'profile'=>'极速数据平台提供各类生活数据API,方便开发者快速简单的开发APP、软件及其他服务平台。公交、火车、违章、快递等数据应有尽有。',
'admin'=>'Liu',
'create'=>2011,
'test'=>'极速数据'
]
];
foreach ($arr as $key => $value) {
foreach ($value as $key2 => $value2) {
if($value2 != '极速数据')
break;
echo $key2, ' : ', $value2, PHP_EOL;
}
}
/* 输出:
name : 极速数据
*/
示例代码仅将continue
改为break
,但结果只输出了二维数组的第三个元素(也是一个数组)的第一个值为“极速数据”的键值对。这里说的有点绕,但是如果二维数组中每个数组的第一个元素值不是“极速数据”的话,这段代码将没有输出!
这也是break
与continue
之间的不同之处。
在使用上,continue
与break
类似,同样可以接受一个数字型参数来决定跳出几层循环到循环末尾,默认值也同样是1
。请看下面的示例代码:
<?php
// continue 多重循环示例
$arr = [
['一个', '很随便', '的', '数组', '混进了', '听起来', '很高大上的', '二维数组', '我还故意加了一个值','极速数据','来检测多重循环', '还在同一数组添加了另一个相同的值', '极速数据', '来验证continue'],
[1, 2, 3, 4, 5, 6, 7, 8],
[
'name'=>'极速数据',
'host'=>'https://www.jisuapi.com/',
'columns'=>['PHP教程', 'Python教程', 'HTML5教程', 'Javascript教程'],
'profile'=>'极速数据平台提供各类生活数据API,方便开发者快速简单的开发APP、软件及其他服务平台。公交、火车、违章、快递等数据应有尽有。',
'admin'=>'Liu',
'create'=>2011,
'test'=>'极速数据'
]
];
foreach ($arr as $key => $value) {
foreach ($value as $key2 => $value2) {
if($value2 != '极速数据')
continue 2;// 跳到第二层循环后开始下一次循环
echo $key2, ' : ', $value2, PHP_EOL;
}
}
/* 输出:
name : 极速数据
*/
分析上方代码及结果可知,本段代码仅查找二维数组里每个数组中第一个元素值为“极速数据”的键值对。
在实际开发中,会遇到特别复杂的流程控制,应该根据不同情况选择使用不同的中断语句。即使我们已经知道break
与continue
不同,但有时候修改流程的代码顺序得出结果可能就会一样。在后续的章节中也许会遇到,这里不做过多讲解。
return
return
与前面的break
和continue
不同,它的使用非常广泛,常见于函数体。如果用在脚本文件,将会立即结束脚本的运行。例如:
<?php
// return
// 一段运行的代码
echo 'PHP是世界上最好的语言';
// return 一下
return;
// 被 return “阻拦”的代码:不会运行
echo '可怜巴巴';
// 整个脚本将输出:PHP是世界上最好的语言
在函数中,如果调用return
语句,将会立刻结束函数的执行。同return
名称所暗示的,return
是可以接受参数作为返回值的。例如:
<?php
// 一个不带 return 的函数
function demo()
{
echo '我是一个莫得感情的杀手:我不带返回值', PHP_EOL;
}
$res = demo();// 执行 demo() 函数并将其返回值(不带返回值则返回 NULL)赋给 $res 变量
var_dump($res);// 输出:NULL
function demo2()
{
echo '我是一个莫得感情的杀手:带的返回值和没带一个样', PHP_EOL;
return;
}
$res = demo2();// 执行 demo() 函数并将其返回值(不带返回值则返回 NULL)赋给 $res 变量
var_dump($res);// 输出:NULL
// 一个带 return 返回值的函数
function demo3()
{
echo '我是一个感情丰沛的诗人:我留下了一个返回值',"\n";
return TRUE;// 可以是任何类型
}
$res = demo3();// 执行 demo() 函数并将其返回值(不带返回值则返回 NULL)赋给 $res 变量
var_dump($res);// 输出:bool(true)
需要注意的是,return
与echo
一样属于语言结构,而不是函数,其参数不应该使用圆括号括起来。另外,return
只能接受一个参数,若要返回多个数据,可以选择将数据存入数组返回:
<?php
function demo()
{
$val1 = '一个值';
$val2 = '极速数据';
$val3 = 666;
// 返回多个数据:使用数组
return [$val1,$val2,$val3];
}
$res = demo();
var_dump($res);
/* 输出:
array(3) {
[0]=>
string(9) "一个值"
[1]=>
string(12) "极速数据"
[2]=>
int(666)
}
*/
有关PHP的流程控制我们就讲到这里,截止到本章,PHP 的许多基础概念我们也都学习完毕。下一章我们进入函数的学习!