思考PHP语言一:控制结构
【概述】
命令式程序设计语言的实质是赋值语句占主导地位。 赋值语句的目的是改变变量的值,因此在所有的命令式程序设计语言中,其共同部分就是不停的变幻变量的值,最后达到我们的目的。
然而我们的程序并不是仅仅是由赋值语句组成的。至少还需要两种额外的语言机制:
1、控制路径选择的方法。
2、控制某些语句重复执行的方法。
这些方法或语言机制我们称之为控制语句。
大量的控制语句可以提高程序语言的可写性,但是同时又会降低程序语言的可读性,为此,经常需要在这二者之间进行权衡。
【PHP中的选择语句】
1、双向选择语句
示例:
1 2 3 4 5 | if (expr) { statement }else{ statement } |
PHP选择语句中的逻辑表达式可以是布尔表达式,也可以是结果为数字的表达式,但是在PHP内部只有一种变量zval,于是这些表达式结果类型对于PHP来说没有多大的意义
在PHP中,then子句和else子句可以是简单语句也可以是复合语句,如果是复合语句需要使用大括号将所有的复合语句括起来。
关于else的归属问题,以就近原则为准,如果需要在一个then子句中包含一个if语句,建议将其以复合语句处理,使用大括号将if语句括起来。如下所示代码:
1 2 3 4 5 6 7 | if (expr) { if (expr2) { statement } }else{ statement } |
2、多向选择语句
多向选择语句允许在任意数目的语句或语句组中进行一种选择。多向选择器与双向选择器可以互相构造,都可以实现对方的功能。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 | switch(expr) { case 常量表达式1: statement 1; break; ...... case 常量表达式n: statement n; break; [default: statement n + 1;] } |
PHP的switch语句使用了C的switch语句的语法,但是却有一些差别,PHP的case 表达式可以是数字,字符串或浮点数这些简单类型。
与双向选择语句一样,多向选择语句在选择的路径上可以是简单语句,也可以是复合语句,只是这里我们不需要使用大括号,此时我们可以叫它语句序列。
当所有的情况都不满足时,执行default路径,如果没有所谓的default情况,请将default子句也写上,并且报错吧。
但是,当出现了switch选择语句时,此时可以想想我们的代码是否可以重构了。
当某个case下没有 break语句时,请写下注释说明原因。
【PHP中的循环语句】
循环语句的作用是将一条或一组语句执行n(n>=0)的一种语句
在函数式程序设计语言中一般是通过递归完成循环语句的功能
1、计数器循环控制语句
这种形式的循环控制语句一般包括初始值,终值,步长,这些统称为循环参数
PHP的计数器循环控制语句是类似于C语言的。
示例如下:
1 2 3 | for (表达式1; 表达式2;表达式3) { 循环体 } |
这就是我们所说的for语句,只是在PHP中,for语句的使用较少,用得最多的还是在后面会提到的基于数据结构的循环—foreach
for语句中的三个表达式都是可选的,如果缺少第二个表达式,则认为其结果为真,如果在循环体中没有退出操作的话,这将是一个死循环。并且每个表达式都是可以由多条语句组成,语句与语句之间用逗号隔开,此时表达式的值为最后一条语句的值。
虽然for语句属于计数器循环控制语句,但是它并没有明显的循环变量或循环参数,可以在循环体中改变所有的所有变量,这就导致了for语句的灵活性,同时,如果用得不好也将导致程序逻辑的混乱
2、逻辑控制循环语句
逻辑控制循环语句是基于布尔表达式的,所有的计数循环都可以使用逻辑循环来实现,反过来则不一定。
示例:
1 2 3 4 5 6 7 | while (控制表达式) { 循环体 } do { 循环体 }while(控制表达式); |
逻辑控制语句分为先测试和后测试两种情况,这个在上面的示例中有所体现。与for语句一样,PHP的逻辑循环控制语句也是类似于C语言的实现。
对于while语句,当控制表达式的条件为真时执行循环体,对于do-while语句,先执行循环体,再判断控制表达式是否为真。while语句总会比do-while语句少执行一次。
3、基于数据的循环语句
顾名思义,基于数据的循环语句的循环是由数据结构中的元素的数目来控制的。一般来说,基于数据的循环语句会使用一种称之为迭代器的函数来实现元素的遍历。
PHP中可以使用预定义的一些函数来实现对数组的迭代访问,如current,next,reset等等。
然而我们使用得最多的还是foreach语句,foreach可以直接迭代访问数组,如果用户自己定义的对象需要使用此语句进行迭代访问,必须实现SPL的迭代器。
之前写过两篇关于迭代器的文章:
PHP中迭代器的简单实现及Yii框架中的迭代器实现
PHP源码阅读笔记二十四 :iterator实现中当值为false时无法完成迭代的原因分析