3.PHP流程控制

2019-05-08  本文已影响0人  好像在哪见过你丶

思考:平常针对业务需求编写的代码通常以行为单位,那么代码的执行逻辑是什么样子的呢?

引入:正常情况下,代码就是按照编写的顺序从上往下逐行执行的,但是我们不能确保用户在操作的时候就完全按照指定的代码流程执行。所以,在这个时候,就会需要用到一些流程控制来确保代码能够按照正确的方向执行。

流程控制【了解】

定义:所谓流程控制,就是在代码逻辑中增加一些“开关”,让代码可以按照正常的业务需求运行到最后。

1.在PHP中,流程控制分为三种:顺序结构、分支结构和循环结构

<?php
//定义变量
$a = 100;        //PHP解释器先解释第一行代码
//输出结果    
echo $a;         //PHP解释器顺序执行第二行代码
?>

总结:代码的流程控制是程序员开发程序时要掌握的基本技巧,也是程序能够解决复杂的业务需求的根本所在。


分支结构

思考:用户在网购的时候需要选择支付方式,我们的代码实现是根据用户选择的方式来动态生成支付代码的吗?

引入:代码理论上到目前为止还没有所谓动态生成的概念,即根据用户不同的选择来临时生成解决方案,都是先把能够支持用户操作的代码写好,只是随着用户的选择而执行不同的代码而已。

IF分支结构【掌握】

定义:IF是如果的意思,言外之意是如果某种条件达到,再去执行某一件事。IF分支就是根据条件来分出不同的“支流”,每个支流有对应的解决方案。if中所有条件需求的结果都是使用布尔类型,如果提供的是非布尔类型,那么系统会自动转换成布尔结果

1.IF分支语法:if分支根据业务的复杂性可以分为三种,即简单if分支、标准if分支和复杂if分支
2.简单if分支:简单的if分支是只有一个代码块,达到某个指定的条件才会执行,否则不执行对应的代码块。语法规则为:
if(条件){
  满足条件要执行的代码块
}

<?php
//只支持支付宝支付
$choice = '支付宝';
if($choice != '支付宝'){
    //条件匹配:用户的选择不是支付宝 $choice != '支付宝' 结果为true
    echo '目前仅支持支付宝支付';
    exit;                            //表示代码终止执行
}
?>

3.标准if分支:通常是要解决条件的满足于不满足情况,满足条件时对应的代码块会执行,不满足条件时对应的另外一个代码块会执行:言外之意两个代码块一定执行其中一个(只有一个)。语法规则为:
if(条件){
  满足条件要执行的代码块
}else{
  不满足条件要执行的代码块
}

<?php
//如果不是支付宝支付就是微信支付
$choice = '支付宝';
if($choice == '支付宝'){
    echo '支付宝支付';
}else{
    echo '微信支付';
}
?>

3.复杂if分支:这种通常是条件对应的结果通常会大于两个,不是非黑即白。因此在进行一轮条件匹配后,还要进行第二轮甚至更多轮的条件匹配。语法规则为:
if(条件1){
  满足条件1要执行的代码块
}elseif(条件2){
  满足条件2要执行的代码块
... //表示可以有任意多个条件
}else{
  不满足全部条件要执行的代码块
}

<?php
//支持多种支付
$choice = '微信';

if($choice == '支付宝'){
    echo '支付宝支付';        //如果条件满足为支付宝,那么执行支付宝支付
}elseif($choice == '微信'){
    echo '微信支付';          //如果条件满足为微信:那么支付宝条件不满足,执行微信支付
}else{
    echo '其他支付';          //如果条件不是支付宝也不是微信,那么执行其他支付
}
?>

4.在PHP中elseif和else if同时支持,效果等同。

<?php
//支持多种支付
$choice = '微信';

if($choice == '支付宝'){
    echo '支付宝支付';        //如果条件满足为支付宝,那么执行支付宝支付
}else if($choice == '微信'){
    echo '微信支付';          //如果条件满足为微信:那么支付宝条件不满足,执行微信支付
}else{
    echo '其他支付';          //如果条件不是支付宝也不是微信,那么执行其他支付
}
?>

5.其实多条件分支(复杂if分支),也可以使用标准分支来实现,但是这个使用需要使用if嵌套:即在else的代码块中再次使用if进行条件判断

<?php
//支持多种支付
$choice = '微信';

if($choice == '支付宝'){
    echo '支付宝支付';        //如果条件满足为支付宝,那么执行支付宝支付
}else{
    //所有不是支付宝支付条件都会进入到else中,可以在else中再次筛选条件
     if($choice == '微信'){
        echo '微信支付';      //如果条件满足为微信:那么支付宝条件不满足,执行微信支付
     }else{
         echo '其他支付';     //如果条件不是支付宝也不是微信,那么执行其他支付
     }
}
?>

6.IF分支注意事项:如果条件变换是有序渐进的,那么在渐进条件编写的时候,一定要注意条件变换的顺序性,以及发生条件区间封闭性。如按照年龄来划分人所处某一类人的时候,一定是最狭窄的条件先判定(满足的概率偏小),最后是最宽的条件。

<?php
$age = 50;

if($age <= 20){        //年龄小于20是最狭窄的,不能先年龄小于50或者更大
    echo '青少年';
}elseif($age <= 50){
    echo '中年';
}else{
    echo '老年';
}
?>

7.练习:如果上述案例想做成不论条件顺序都不会出错,请问要如何实现?

总结:IF分支结构在日常代码编写中非常常见,因为业务的操作通常为了表示用户的友好性,会在很多地方给用户提供条件选择。而且在业务代码发展过程中,会经常根据运算结果进行不同的操作,也会用到分支结构。if分支有多种,具体选择规则如下:


思考:IF分支结构能够处理全部条件判断需求,但是如果条件很多的时候,要写很多的if-else语句块,结构会显得很臃肿,有没有其他简洁一点的方法呢?

引入:如果条件在不是很统一的情况下,即便真有这样的需求也确实需要使用复杂IF结构,但是如果条件很多,但是每个条件都是很明确的情况下(具体常量:此常量非PHP常量,而是具体的数据,如数值或者字母),确实有一种能够更方便的方法,那就是Switch分支结构。

Switch分支结构【掌握】

定义:Switch也是一种通过条件匹配来选择执行代码块的分支结构,但是Switch的条件只有一个(只需要写一次),而且运行机制与if分支结构不一样。

1.基本语法
switch(条件变量){
  case 匹配值1:
    //满足条件执行的代码块;
    break; //结束分支结构
  case 匹配值2:
    //满足条件执行的代码块;
    break;
  ...
  default:
    //条件都不匹配执行的代码块;
    break;
}
2.语法解释:

<?php
//根据用户的选择来选择对应的支付方式
$choice = '支付宝';

switch($choice){
    case '支付宝':
        echo '支付宝支付';    //当$choice的值为支付宝时执行
        break;              //执行结束后结束switch:如果没有break,继续执行微信的代码块,直到遇到break或者switch结束
    case '微信':
        echo '微信支付';
        break;
    case '比特币':
        echo '比特币支付';
        break;
    case '储蓄卡':
        echo '储蓄卡支付':
        break;
    default:
        echo '现金支付';
        break;            //最后一个break可以省略(不管是不是在default后)
}
?>

3.switch分支与if分支的区别

4.练习:根据给定的数字1-7输出对应的星期几。

总结:Switch分支结构是用来处理条件多且有规律的分支情形,相对于if有优势也有劣势(条件匹配不够灵活)。在实际开发中要根据当前业务的数据特点来选择对应的分支结构。


循环结构

思考:有一些业务情况下,可能需要某些代码重复执行N次,难道在编写代码的时候,是将一行代码复制多行来解决吗?

引入:实际开发中,的确有很多情况下,需要某些代码在部分有规律变化的情况下,重复的执行,为了解决这一问题,提升程序员的开发效率,系统提供了循环结构来控制执行重复代码。

for循环【掌握】

定义:for循环是一种能够在循环结构内部设定初始化条件、边界值以及条件控制的循环结构,也是一个将条件与要重复执行的代码分开管理的一种循环结构,通常是根据某些有特定变化规律的条件来实现。

1.基础语法

for(初始化条件;条件判定;条件变更)
{
  //要重复执行的代码(循环体)
}
2.解释

<?php
//输出1-100之间的整数
//分析:初始条件应该是从1开始,结束条件应该是数据大于100,条件的变化每次是1(整数)
for($i = 1;$i <= 100;$i++){
    echo $i,' ';                   //echo后可以使用逗号分隔输出多个内容
    //初始化条件:   $i = 1         //只执行一次:第一次
    //条件判定:     $i <= 100      //执行101次,$i最后一次为101
    //循环体:       echo $i,' '    //执行100次
    //条件变更:     $i++           //$i每次在原来基础上+1(执行100次)   
}

//循环后使用条件变量
echo $i;                           //101,第一个大于边界值100的数据
?>

3.特殊情况下使用for条件:for循环的条件并非一定需要,如果本身在循环内部(循环体)就可以控制循环的执行(不要成为死循环),for循环中的初始化条件、条件判定和条件变更可以都不需要

<?php
//无条件for循环:极端使用,初始化条件、条件判定和条件变更都没有
for(;;){
    //没有任何循环条件
    //循环体
    //一定要有循环控制(后学),要不然就是死循环(导致内存崩溃)
}
?>

4.练习:输出1到100之间所有数的立方和。

总结:for循环多用于有规律的数值条件循环,能够通过条件的起始和结尾来对循环本身进行控制。


思考:for循环是比较适合规律性数值条件的循环,如果有些条件没那么明显的情况下,还能使用循环吗?

引入:循环通常只要有确定的条件即可,for循环是比较适合规律性数值条件的循环,但是其实也可以应用在规律性不强的条件方面,只是通常还有其他循环方式,如while循环。

While循环【掌握】

定义:while循环,是一种在循环外定义初始化条件的一种循环方式。

1.基础语法

while(循环条件)
{
//循环体
}
2.解释:while循环通常是在循环外部定义循环条件(条件变量),然后在循环体中执行循环条件的变化

<?php
//输出1到100的整数
$i = 1;            //定义初始化变量
while($i <= 100){
    //循环体
    echo $i;       //如果到这结束:那么循环就进入死循环,因为$i永远为1,从而小于等于100
    //变更循环条件
    $i++;          //在循环体中控制循环变量   
}
?>

3.while循环与for循环的区别:二者没有本质区别,都可以实现各种循环。区别在于形式上:for循环是将条件与循环体控制在for循环自己内部,而while循环通常需要在外部定义循环条件,同时如果是需要手动条件变更,则需要在循环体中出现。
4.练习:输出1-100之间所有的基数。

总结:while循环和for循环一样都可以解决循环问题,for循环通常用来解决那些条件明确的循环,while循环通常用来解决一些条件不够确定的循环(不知道什么时候结束)。


思考:for循环和while循环都是先判定条件后执行循环的结构,如果有时候想不论如何都执行一次循环该怎么实现呢?

引入:首先在循环结构要解决的业务情形中,这种绕过条件先执行循环体的需求很少。但是也并非没有,如果有需要的话可以使用do-while循环。

do-while循环【了解】

定义:do-while循环,顾名思义,先“做”后循环,即先执行循环体,后判定循环条件来决定是否继续执行。

1.基础语法

do{
//循环体
}while(条件); //注意:因为do-while不是花括号结束,所以需要使用语句结束符
2.解释:do后跟循环体,表示循环一开始先执行循环体,后判定while中的条件:条件符合继续执行循环体;条件不符合结束循环

<?php
//求100以内的基数和
$i = 1;
$res = 0;            //定义先决条件

do{
    $res += $i;      //累计求和
    $i++;            //条件变更
}while($i <= 100);   //条件判定
?>

3.do-while与while的区别:do-while和while都是执行循环,区别在于while是先判定条件,而do-while是先执行循环体。言外之意,while有可能循环体一次都不执行,而do-while一定会执行至少一次。

总结:do-while在PHP实际开发应用中,使用的很少。实现的效果比while循环通常不过是少一次条件判定,这个在PHP效率中不值得特别计较。但是do-while在C语言中使用还是比较多的(宏)。


思考:以上循环都是针对单个有规律或者无规律的变化而实现的循环功能,但是如果有一个数组想要输出其全部的下标和值该怎么办?

引入:对于索引数组而言(下标全部为数字),其实可以使用以上任意一种循环来实现(假设下标从0开始即可),在循环内部通过自增长下标来实现即可。但是这样并非绝对,尤其是在关联数组下,以上循环模式的确有些乏力,所以PHP额外提供了一种专门针对数组遍历的循环方式:foreach循环

foreach循环【掌握】

定义:foreach循环,是PHP中一种特定为数组设定的循环结构,能够方便的将数组的下标和值挨个取出来,从而实现对数组的所有元素的访问。

1.基础语法

foreach(数组变量 as [存储下标的变量 =>] 存储值的变量){
  //访问存储下标的变量和存储值的变量
}
2.解释

<?php
//遍历数组中所有的元素下标和值
$arr = array('name' => '张三','age' => 30,'gender' => '男');

foreach($arr as $k => $v){
    //$k代表取出的数组元素的下标(变量名字可以随便取)
    //$v代表取出的数组元素的值(变量名字可以随便取)
    echo $k . ' : ' . $v . '<br/>';
}
//循环外访问内部变量
echo $k . ' : ' . $v . '<br/>';        //最后一个元素值:gender : 男

?>

3.foreach遍历原理:每个PHP数组内部有个指针,默认指向数组元素的第一个

4.二维数组遍历:按照前面所学,二维数组通常是第一维为索引(下标为数字),第二维为关联(下标为字母),所以在遍历的时候,通常只需要进行一层foreach即可:即遍历出第一维,然后第二维可以通过下标访问。

<?php
//遍历二维数组
$info = array(
    array('name' => '张三','age' => 30,'gender' => '男'),
    array('name' => '王婆','age' => 75,'gender' => '女'),
    array('name' => '小李','age' => 18,'gender' => '男')
    );                //二维数组:第一维为索引,第二维为关联
    
foreach($info as $p){
    //第一维为索引:所以通常下标无具体含义,因此不需要下标
    //$p就是数组$info中具体的每个元素:一个一维的关联数组
    echo '姓名:' . $p['name'] . ' 年龄:' . $p['age'] . ' 性别:' . $p['gender'] . '<br/>';
}
?>

5.练习:利用for循环,增加一个拥有10个数组元素的二维数组:第二维对应的信息是stu_no(学号),stu_age(年龄),stu_name(名字),stu_major(专业),对应的值是:学号(no+顺序数值),年龄(18+顺序数值),名字(name+顺序数值),专业(major+顺序数值);然后再利用二维数组,输出所有学生的信息。

总结:foreach循环的目标很明确,就是针对数组元素的遍历,能够方便程序员在遍历的时候得到数组元素的下标和值。如果二维数组本身都是索引或者关联,而且需要所有元素的下标和值,那么进行两层循环即可。


思考:循环一旦指定了外部条件就会自动运行,不需要任何管理控制,但是如果在循环内部某些业务需求需要对循环做出一些调整的话有没有什么办法呢?

引入:通常情况下,循环都是在外部就可以控制好的,这是循环的本质。但是的确会有那种需要在循环内部对循环进行一些控制的时候,这个时候就需要用到循环控制。

循环控制【掌握】

定义:循环控制,即在循环进行之后,在循环内部(循环体)使用特定的语法来选择让循环按照某种特定的方式去执行或者终结执行。

1.循环控制分类:循环控制分为continue和break

<?php
//求和:1到100之间所有的基数和
for($i = 1,$res = 0;$i <= 100;$i++){    //此处初始化条件定义了两个值
    //判断:$i是否是基数
    if($i % 2 == 0){
        //模运算:如果结果为true:说明$i是2的倍数,即偶数
        continue;    //代码不再继续:重新开始下一次循环:即$i++
    }
    //满足条件:基数累加到结果
    $res += $i;
}
?>
<?php
//求出立方数大于10000的最小整数:N ^ 3 > 1000
$i = 1;          //从1开始算
$min = 0;        //设定初始值用来保存最终目标值
//使用while循环:因为不清楚要循环多少次
while(true){     //条件不限定:不清楚
    //计算判定
    if($i * $i * $i < 10000){
        //变更条件
        $i++;
        continue;                        //循环重新开始
    }
    
    //能够执行到这的:说明$i * $i * $i的值大于或者等于10000
    $min = $i;                           //拿到想要的结果
    
    //但是此时循环无法终止:会一直运行,因为while条件是永远为true,所以要内部结束
    break;
}
?>

2.PHP中循环控制的特点:在PHP中,循环控制不只是能够控制本层循环,而且可以通过指定循环层次控制到其他循环。具体特点就是在continue/break后跟上指定要控制的循环层数,默认是1,即本层循环(可以不写)

<?php
//控制两层循环:求1到100的所有值相乘的结果,但是第一个乘数比第二个乘数大
for($i = 1;$i < 100;$i++){
    //外层循环
    for($j = 1;$j < 100;$j++){
        //$i是第一个乘数,$j是第二个乘数:判断
        if($j > $i){
            //第二个乘数大于第一个乘数:内存循环所有都没有意义了
            //continue;    //如果使用continue,表示当前内存循环继续执行,即改变$j,没有价值
            continue 2;    //表示:当前循环的外层重新执行:即改变$i
        }
        
        //输出
        echo $i . ' * ' . $j . ' = ' . $i * $j;    //输出 1 * 1 = 1
    }
}
?>

3.练习:1,用你认为最优化的方式,制作一个保存100个斐波那契数列数组。斐波那契数列:第一个和第二个数为1,后面的数字都为前两个数字之后:如1,1,2,3,5...;2,求出100以内的所有质数。质数:只能被自己和1整除

总结:循环控制是在循环实现基础上增加的一种内部控制机制,目的就是为了更好的适应业务需求,方便程序员在循环中去控制循环正确的执行。


思考:数据的展示最终是给用户看的,而用户看到的结果一定是在HTML中显示的,言外之意,PHP要将用户需要的数据在HTML中展示出来。那么PHP到底是如何跟HTML结合的呢?

引入:PHP本身是一种可以嵌入到HTML中显示的脚本语言,所以PHP只需要在HTML中获取到数据,并且将数据在HTML对应的结构中显示出来即可。PHP中在HTML中要显示的数据最常见的数组数据,批量显示,所以会需要用到PHP代码和HTML中常用的表格(table)来进行综合数据展示。在进行数据展示过程中,有两种方式:第一种是PHP中直接输出对应的table标签字符串,第二种是PHP代码与table标签嵌套,但是分开工作(建议)。为了方便显示和维护,PHP提供了一套类似HTML标签的标签语法。

PHP标签语法

定义:PHP标签语法,是PHP为了更好的方便前端人员和后端人员分开维护共同的代码而设计的类似HTML中的标签方式的语法。PHP中的标签语法不多,支持的标签语法有if和各种循环。

1.PHP嵌入到HTML中实现数据显示

<?php
//在PHP中定义获取一个数组
$info = array(
    array('name' => '张三','age' => 30,'gender' => '男'),
    array('name' => '王婆','age' => 75,'gender' => '女'),
    array('name' => '小李','age' => 18,'gender' => '男')
    );   
?>
<!--在HTML中显示数据-->
<html>
<head></head>
<body>
    <table>
        <th>
            <td>序号</td>
            <td>姓名</td>
            <td>年龄</td>
            <td>性别</td>
        </th>
        <!--PHP数组中每一个元素对应的就是table标签的一整行,所有有多少个元素就会产生多少行,因此只要针对元素遍历即可-->
        <?php foreach($info as $k => $p){?>
            <!--注意:此处将foreach的{}分开到两个PHP语句块中:是为了中间方便嵌入HTML代码-->
        <tr>
            <td><?php echo $k + 1;?></td><!--注意:二维数组的第一维索引是从0开始,所以在显示的时候,通常+1操作-->
            <td><?php echo $p['name'];?></td>
            <td><?php echo $p['age'];?></td>
            <td><?php echo $p['gender'];?></td>
        </tr>
        <?php }?>
    </table>
</body>
</html>

2.HTML中嵌入的PHP代码解析原理:PHP在HTML中嵌入的时候,通常都是多块PHP代码分散到HTML中,而且很多时候都是循环出现。其解析原理其实与原来一样:

3.以上方式在显示的时候有些别求,尤其是{}拆开,而且如果在有多个{}嵌入的时候(比如说判定),那么就会显得非常凌乱,因此PHP中可以将if,for,while和foreach使用标签语法来显示,避免出现PHP对应的{}

<?php
//在PHP中定义获取一个数组
$info = array(
    array('name' => '张三','age' => 30,'gender' => '男'),
    array('name' => '王婆','age' => 75,'gender' => '女'),
    array('name' => '小李','age' => 18,'gender' => '男')
    );   
?>
<!--在HTML中显示数据-->
<html>
<head></head>
<body>
    <table>
        <th>
            <td>序号</td>
            <td>姓名</td>
            <td>年龄</td>
            <td>性别</td>
        </th>
        <?php foreach($info as $k => $p):?>
        <tr>
            <td><?php echo $k + 1;?></td>
            <td><?php echo $p['name'];?></td>
            <td><?php echo $p['age'];?></td>
            <td><?php echo $p['gender'];?></td>
        </tr>
        <?php endforeach;?>
    </table>
</body>
</html>

4.练习:使用两种方式在表格中输出九九乘法表,table的border为1。方案1:所有的HTML代码都是通过PHP的字符串输出形式存在,如echo '<tr>';所有的HTML代码都与PHP分离,PHP只负责显示数据。

总结:标签语法看似不起眼,因为本身没有额外的区别,只是为了解决{}的问题。但是在实际开发中,通常数据显示的时候会存在逻辑判定if,会导致会有很多个{}分开,如果在层次不清晰的情况下,会看起来非常啊头疼,不好管理。所以标签语法能够解决人眼清晰的问题。

上一篇下一篇

猜你喜欢

热点阅读