语句
一般的编程语言通常都以语句为基本单位,程序由多条语句构成。PHP中,分号标记了一个语句的结束,并且一条语句必须以分号作为结束。
任何具有意义的程序代码都可以作为一条语句。例如之前提到的表达式
倘若在后面加上一个分号,就成了一条语句。
$c=$a+$b;
正常情况下,PHP程序是从上到下按照语句的排列顺序来执行,如果想要完成更复杂的业务逻辑,则需要借助控制结构。和其他的编程语言相同,PHP也具有选择结构和循环结构。
控制结构可以改变语句的执行顺序,使得原本单调的顺序结构得以扩展,让程序可以解决更复杂的问题。
##语句块 语句块由多个语句组成,包含在花括号中。语句块通常表示一组功能上有关联的代码,通常在选择结构、循环结构、函数上使用。
选择结构
选择结构会使程序流程增加分支,程序运行到分支处时,会根据选择条件的判断结果来决定执行哪一个分支。如果你在数学课上学习过程序框图的话,这张图你一定不会陌生:
上图是一个最简单的if选择结构。通过多个if结构堆叠起来,可以实现更多分支的选择结构,例如:
但是在编写代码的过程中,这样写是非常冗余的,而且也不利于维护。如果想要表达一个平行的多分支选择结构,通常会是这个样子
上述三种结构,都是很常见的选择结构。下面我们将介绍如何使用代码来表达这三种结构。
if-else选择结构
结构实现的是单条件选择,通常的形式是这样的:
if($cond){
//do something
}else{
//or do another thing
}
$cond可以是一个值,也可以是一个变量,更常见的是一个逻辑表达式。当$cond的值为true时,执行if下面花括号中的语句块,否则执行else中的语句。例如下面一段代码。
//choose.php
$a=$_GET['a'];
if($a>){
echo'a大于0';
}else{
echo'a不大于0';
}
是PHP自带的超全局变量,可以用来获取get方式传过来的变量值。这部分内容会在后面进行详细讲解。这里可以理解为是获取一个值,这个值来自你访问的url。
运行这段代码。首先访问,得到的结果是
修改访问的url,访问,得到的结果是
在这段程序中,首先我们从get参数中获取到了$a的值,并根据$a的值的不同情况,分别给出不同的处理。
当业务逻辑复杂起来,需要我们处理更多种情况的时候,可以叠加使用if-else结构。我们接下来看一个具体的问题。
某小学成绩和成绩等级对应如下表:
现需要编写程序,输入成绩等级,程序会给出对应的成绩区间。
如果使用if-else结构,我们这样编写代码:
//scoreAndRank.php
$rank=$_GET['rank'];
if($rank=='A'){
echo'该同学的成绩区间是:100~80';
}elseif($rank=='B'){
echo'该同学的成绩区间是:79~60';
}elseif($rank=='C'){
echo'该同学的成绩区间是:59~40';
}elseif($rank=='D'){
echo'该同学的成绩区间是:39~20';
}elseif($rank=='E'){
echo'该同学的成绩区间是:19~0';
}else{
echo'输入的成绩等级不合法';
}
尝试运行代码
我们看到,当分支情况复杂起来的时候,if结构也会变得异常复杂。上面的例子只是简单的叠加情况,代码就冗余成这种程度。通常当我们需要处理一系列平级的选择条件时,通常会使用switch结构。
switch结构
switch结构是选择结构的另一种方式,通常用来处理具有多个平行条件的选择结构。switch结构通常的形式是这样的:
switch($value){
case$value1: do_something_1();break;
case$value2: do_something_2();break;
case$value3: do_something_3();break;
...
default: do_default_thing();
}
程序会将value与下面每一个case后面的value比较,执行值互相匹配的case后面的语句。会使程序在执行完对应的功能之后退出switch结构。关于的作用会在循环结构中详细讲解。
case匹配之后执行的语句可以是一条,也可以是一个语句块。case后面的结构也可以是这个样子:
switch($value){
case$value1: {
do_something_1_1();
do_something_1_2();
}break;
...
}
如果没有任何一个case与value相匹配,则执行default后面的语句。如果没有default情况,则直接跳出switch结构。
如果使用switch结构处理刚才“成绩-等级”的问题,可以改写成如下代码:
//scoreAndRank.php
switch($rank){
case'A':echo'该同学的成绩区间是:100~80';break;
case'B':echo'该同学的成绩区间是:79~60';break;
case'C':echo'该同学的成绩区间是:59~40';break;
case'D':echo'该同学的成绩区间是:39~20';break;
case'E':echo'该同学的成绩区间是:19~0';break;
default:echo'输入的成绩等级不合法';
}
default情况不是必须的,但是通常具有一定经验的程序员,都会在switch结构中补齐default情况。这样可以使程序结构和逻辑更加完整,而且可以避免出现一些不可预料的情况。
switch结构也有一定的缺陷和局限性。switch结构只能处理“等于”的情况。思考一下,如果将上述问题改为“输入成绩,输出成绩等级”,这时switch结构就没有办法应付这个问题。
if和switch两种结构各有各的优势和劣势,在实际编程中应灵活变通。选择最适合的语句结构,程序才会有最优的效率。
循环结构
除了选择结构外,另一种结构就是循环结构。通常我们会用循环结构来处理“需要反复处理”的问题。循环结构会让程序在运行过程中的某几步之间往复进行,当满足某一些条件的时候再跳出循环结构。用框图表示一个最普通的循环结构如下图所示:
我们来看一个具体的问题。
使用程序求1~100自然数的和。
这个问题在数学中再简单不过了,使用数学上的求和符号,一步就算出了结果。
使用程序解决这个问题,实际上和求和符号的原理相同,都是用了“循环”的思想。PHP有三种方式来描述选择结构,接下来我们将借助这个简单的求和问题来一一认识它们。
while结构
while结构的一般形式是:
while($cond){
//do something
}
当$cond成立,就一直执行花括号内的语句块。使用while解决上面的求和问题,代码可以这样写:
//sum.php
$a=;$sum=;
while($a
$sum+=$a;
$a++;
}
echo'1~100的和是:'.$sum;
这里的可以写成
在程序中,当系统读到时,会先读取a的值来进行相关运算,之后再将a的值增加1。相反地,如果使用,则会先将a的值增加1,再读取加1后的值来进行相关运算。和同理。
do-while结构
do-while结构的一般形式是:
do{
//do something
}while($cond)
do-while会先执行语句块,再判断$cond是否成立,如果成立则重复语句块的内容。与while结构相比,do-while会先执行后判断。在这二者中,需要根据具体的情形来选择需要使用哪一个结构。二者都是循环结构,在本质上并无太大区别,只是有时候使用do-while会比使用while更容易思考问题。
for结构
for结构的一般形式是:
for(语句1; 语句2; 语句3;){
//do something
}
for结构的运行流程是这样的。
for结构是最常用的循环结构。上面的求和问题如果改写成for结构的话,代码可以改写成:
//sum.php
for($i=,$sum=;$i
$sum+=$i;
}
echo'1~100的和是:'.$sum;
for结构的强大之处在于,上面所说的三条语句,可以理解为“程序的三个时刻”,并不一定要局限于三条语句。第一个位置通常被称为“初始状态”,第二个位置被称为“循环条件”,第三个位置则是每次循环过后需要处理的内容。
如上面的代码所示,初始状态中我们为$i和$sum赋了初始值,这里用逗号连接了两条语句。而第三个位置中的$i++,实际上也可以写在语句块之内。
改变循环状态
为了体现编程不是那么简单的,我们不能用一个求和的问题来来回回算了好多遍。那现在我们来考虑另外几个循环的问题。
问题8.1:计算自然数1~1000中,全部偶数的和。
问题8.2:自然数中,从1开始计算总和,直到遇到500以后的第一个3的倍数。
基于上述两个问题,我们来介绍continue和break语句。
continue语句
在循环体内使用continue语句时,会跳过本次循环,直接开始下一次循环。用流程图表示的话是这个样子的:
考虑上面的问题8.1。如果要计算全部偶数的和,那我们就循环1~1000,遇到奇数跳过(continue)就可以了。下面我们编写代码。
//sum2.php
for($i=1,$sum=;$i
if($i%2==){
//两数相除,余数是0则为可以整除
//一个数如果能被2整除,则这个数是偶数
$sum+=$i;
}else{
continue;
}
}
echo'自然数1~1000中,全部偶数的和是:'.$sum;
为了让continue的效果更直观,我们在else中加一句
echo$i.'被跳过了。
';
运行这段代码,我们看到结果是
在运行结果中看到,所有的奇数都被跳过,所有的偶数都被加入了总和中。在continue语句的帮助下,这个问题就解决了。
break语句
与continue相比,break就显得很绝情。在循环体内使用break语句时,会使当前循环直接结束。break语句在流程图中是这样的:
考虑问题8.2。从1开始循环自然数,先不用决定在哪里停下,因为在解决问题之前谁也不知道500后面的第一个3的倍数是什么。当判断当前的数字大于500并且是3的倍数,就停止循环。在这之前,所有的数字都要加入加和之中。问题构思好了,我们来编写代码。
//sum3.php
$i=;
$sum=;
while(true){
$sum+=$i;
if($i>500&&$i%3==){
break;
}
$i++;
}
echo'遇到500之后的第3的倍数时自然数的总和是:'.$sum.',这个3的倍数是:'.$i;
这段代码的运行结果是
可以看到,在判断条件成立时,break语句使while循环结构直接中断,使程序流程跳转到了循环之外。
goto语句
与选择结构、循环结构相比而言,至少前两者都还是有规律可循的。选择结构会按照判断的条件来使程序进入不同的分支,循环结构则会按照判断条件使程序进行某种往复的工作。但goto语句与二者都不同。作为可以控制程序流程的一条语句,它没有任何规律。goto语句会使程序直接跳转到某一个特定的位置。
goto语句通常与标号同时使用。标号和goto语句通常形式是这样的:
//标号
flag:
//跳转
gotoflag;
我们看这样一段代码。
//goto.php
$f=true;
flag:
echo'程序开始啦~
';
echo'我也不知道接下来会发生什么。
';
echo'goto来啦!
';
if($f){
echo'回到开始!
';
$f=false;
gotoflag;
}else{
echo'程序结束!
如果不设置分支,程序会死循环。
';
}
这段代码的运行结果是
这段代码体现了goto语句标号和跳转的使用方法。
经验丰富的前辈们往往指出,goto语句具有很大的不可控因素,在编程中不推荐使用。但要这样考虑,goto语句作为编程语言中的一部分,一定有它存在的意义。编程过程中一定要按照自己的意愿去做,也就是“把真实的你讲给计算机听”。goto是一把利刃,是一把锋利的双刃剑。善用它,往往会事半功倍。
领取专属 10元无门槛券
私享最新 技术干货