Blogger Information
Blog 54
fans 6
comment 31
visits 107506
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
PHP运算符和流程控制
吾逍遥
Original
1027 people have browsed it

一、学习到的新认识

今天学习运算符和流程控制,相比于 C++和原生 JS,知识点基本相同。不过有几点还是第一次接触

  • PHP 模板语法 不得不说,我以前最讨厌就是在 html 混用 PHP 多分支控制了,那么多大括号{}让人头痛,现在有模板语法好了,写法更简洁。本来想深入理解它是否适用所有{}代码块,查百度竟然没有教程,只能自己测试了,目前知道适用 if、switch、for 和 foreach。
  • 单引号、双引号和反单引号 这个是老师没讲的,起源于 JS 的模板字面量和 PHP 中模板字面量相近写法,不过 PHP 是双引号来拼接字符串和变量,而 JS 是反单引号拼接字符串和变量。在日常字符串中经常使用单引号和双引号,那 PHP 和 JS 对单引号’’、双引号””、反单引号`` 是如何支持和处理呢?它们有什么区别吗?

二、单引号、双引号和反单引号

讲三个引号的区别,是上一篇中遇到灭绝老师在一个演示案例中使用了”{$a}+${b}=”.($a+$b),前面引号中有两个变量,正常 PHP 拼接变量和字符串要使用点连接符,而 JS 的 ES6 新增了模板字面量(或叫模板字符串),使用反单引号来拼接字符串和变量。二者是何等相似。我们在日常字符中经常混用单引号、双引号,那么三个引号在 PHP 和 JS 是如何处理的呢?

1、字符串是使用单引号还是双引号?

正常情况下字符串使用单引号或双引号都可以,但处理方式不同:

  • JavaScript 中是都当成 普通字符串 处理,有变量也当成普通字符串,不过在 对象属性名是建议使用双引号 ,可以和 JSON 格式统一,毕竟 JSON 是目前最流行数据交换格式。当然单引号不报错。
  • PHP 中 单引号是普通字符串,不解析其中的变量 ,而 双引号则是可以解析字符串的变量的,相当于 JS 中的模板字面量

2、JS 模板字面量和 PHP 模板字面量

PHP 模板字面量是我自己定义的,不要太纠结说法,它们功能相近,下面是二者区别:

  • 使用引号不同: JS是使用反单引号(ESC键下方的),而PHP使用双引号。
  • 变量定义不同: 就是声明引号内的哪些是变量, JS 使用\$开头,大括号{}包裹,而PHP 中若字符串只有一个变量可省略{},若是有混合有多个变量或字符串则一定要有{}包裹 。否则会将变量和字符串拼接成新的变量查询报未定义变量错误。
  • 表达式支持不同 JS 的模板字面 支持表达式运算 ,而PHP 只能是简单的变量和字符串拼接
  1. <script>
  2. a=12; b=13; console.log(`a`); console.log('${a}'); console.log("${a}"); console.log(`${a}+${b}=${a + b}`);
  3. </script>

js-quot

  1. <?php
  2. $a=3;
  3. $b=4;
  4. echo "$a",'<br>';
  5. echo "{$a}+{$b}=".($a+$b),'<br>';
  6. // PHP中双引号不支持表达式运算
  7. // echo "{$a}+{$b}={$a+$b}";

php-quot

3、PHP 支持单反引号吗?

  1. echo ``;
  2. var_dump(``);
  3. var_dump(`123`);

php-anti-quot

经测试 PHP 中,若字符串是以 反单引号包裹则返回 NULL ,若是在单引号或双引号中有反单引号则是普通字符串 。本来测试算结束了,自己又手欠测试了反单引号开头报错了,并且单引号不是成对时,后面代码也报错,难道 PHP 中反单引号是什么特殊符号?在网上一查,还真是,它等同于 PHP 中 shell_exec(),就是可以直接通过 PHP 运行本机上的程序 ,对 PHP 是彻底颠覆了观念。至于 shell_exec()用法自己网上可百度,网上还有用 PHP 启动 Python 的。这里我贴上我的测试代码,运行结果是直接启动我 windows 系统中记事本程序。

  1. // var_dump(`1`'23`123`12');
  2. // 反引号等同于下面的shell_exec('C:\Windows\write.exe');
  3. $outExe = `C:\Windows\write.exe`;
  4. // $outExe = shell_exec('C:\Windows\write.exe');
  5. // var_dump($outExe);

尽量不要放弃每次报错的解决,也许就是新知识的起点。

三、运算符

1、算术运算符

序号 运算符 示例 描述
1 + $a+$b $a与$b 的和
2 - $a-$b $a与$b 的差
3 * $a*$b $a与$b 的积
4 / $a/$b $a与$b 的商
5 % $a%$b $a与$b 的余(模)
6 ++ $a++/++$a 先用再加/先加再用
7 -- $a--/--$a 先用再减/先减再用
8 ** 2**4 幂运算:2 的 4 次方,需要 php5.6+版本

下面演示取余运算符的两个应用: 判断当前年份是闰年和限制随机数范围

  1. // 判断闰年
  2. $year = date('Y');
  3. if ($year % 4 === 0 && $year % 100 !== 0) :
  4. echo "{$year}是闰年",'<br>';
  5. else:
  6. echo "{$year}不是闰年";
  7. endif;
  8. // 限制随机数范围
  9. $res=mt_rand()%21;
  10. echo $res;

2、比较运算符

比较运算符: 返回布尔值,常用于流程控制中(if/while/for...)

序号 运算符 示例 描述
1 > $a > $b 大于
2 >= $a >= $b 大于或等于
3 < $a < $b 小于
4 <= $a <= $b 小于或等于
5 == $a == $b 等于 (值相等即可)
6 === $a == $b 全等于(二边值与类型全等)
7 <> $a <> $b 不相等
8 != $a != $b 不相等
9 !== $a !== $b 不全等
10 <=> $a <=> $b 太空船php7+

这里说下 PHP7 新增加的 太空船比较运算符 ,它是 <、=和>的结合体,就是它完成了三个运算符的工作,比较时比较类型,若前者大返回 1,相等返回 0,前者小则返回-1。

  1. $a='5';
  2. $b=4;
  3. $res=$a<=>$b;
  4. echo $res;

3、逻辑运算符

多条件合并求值,返回值是布尔值,常用于流程控制中(if/while/for...)

名称 运算符 示例 描述
and 或&& $a && $b 如果 a 和 b 都为 true,则返回 true
or 或\ \ `\$a \$b` 如果 a 和 b 至少有一个为 true,则返回 true
异或 xor $a xor $b 如果 a 和 b 有且仅有一个为 true,则返回 true
! !$a 布尔值取反

这里讲下逻辑运算符另一种应用: 短路求值&&表示前一个条件为 true 时,后面表达式会计算 ;另一种就是 ||用在函数中判断参数未传时,使用默认值

  1. $username = 'admin';
  2. if($username&&$username === "peter")
  3. {
  4. echo "欢迎您".$username;
  5. }else{
  6. echo 'sorry,您未登陆~';
  7. }

4、 赋值运算符

序号 运算符 示例 描述
1 = $a = 10 将表达式的值赋给变量
2 += $a += 10 $a = $a + 10;
3 -= $a -= 10 $a = $a - 10;
4 *= $a *= 10 $a = $a * 10;
5 /= $a /= 10 $a = $a / 10;
6 %= $a %= 10 $a = $a % 10;
7 .= $a .= 'a' $a = $a . 'a';

提醒的是:1 个=是赋值运算符,而==和===是比较符,返回布尔值。

5、特殊运算符

  • 点连接符:$str1 . $str2返回连接之后的字符串。
  • 三元运算符: 指有三个表达式,2 个操作符,如$a > $b ? 1:0; 当 a 大于 b 时返回 1,否则返回 0,常用于简化双分支

6、运算符优先级

混合运算时要遵循优先级从高到低进行运算 。下面从高到低列出了运算符,同一行中的运算符具有相同优先级,此时它们的结合方向决定求值顺序。另外通过圆括号()的配对来明确标明运算顺序,而非靠运算符优先级和结合性来决定,通常能够增加代码的可读性。

结合方向 运算符 附加信息
clone new clone 和 new
[ array()
++ — ~ (int) (float) (string) (array) (object) (bool) @ 类型和递增/递减
instanceof 类型
! 逻辑运算符
* / % 算术运算符
+ – . 算术运算符和字符串运算符
<< >> 位运算符
== != === !== <> 比较运算符
& 位运算符和引用
^ 位运算符
\ 位运算符
&& 逻辑运算符
\ \ 逻辑运算符
? : 三元运算符
= += -= *= /= .= %= &= \ = ^= <<= >>= => 赋值运算符
and 逻辑运算符
xor 逻辑运算符
or 逻辑运算符
, 多处用到

四、流程控制

1、条件流程控制

if 关键字的条件流程控制三种形式:

  • 单一条件分支结构 if
  • 双向条件分支结构 if…else 。同 C++和 JS 一样,可用三元运算符简化。
  • 多向条件分支结构 if…elseif…elseif…else

这里要注意多向条件分支时 elseif 书写,它是连一起的,而 C++和 JS 是 else if 分开书写。

  1. <?php
  2. $hour = date("H");
  3. if($hour < 6)
  4. {
  5. echo '凌晨好,主人~';
  6. }elseif($hour<9){
  7. echo '早上好,主人~';
  8. }elseif($hour<12){
  9. echo '中午好,主人~';
  10. }elseif($hour<17){
  11. echo '下午好,主人~';
  12. }elseif($hour<19){
  13. echo '傍晚好,主人~';
  14. }elseif($hour<22){
  15. echo '晚上好,主人~';
  16. }else{
  17. echo '别熬夜了!你头发没了~';
  18. }

switch…case: 也是对 if 多向条件分支结构的简化(同 C++和 JS 中一样)

  • 通常用在单值的判断中,每个值为一个分支
  • 也可用在区间判断中,此时要注意 switch 条件是 true,变量真正判断放在 case 中。可参考我 JS 中总结的https://www.php.cn/blog/detail/24740.html
  1. <?php
  2. $week = date("N");
  3. switch($week){
  4. case 1:
  5. echo '你好打工人,今天是工作日周一~';
  6. break;
  7. case 2:
  8. echo '你好打工人,今天是工作日周二~';
  9. break;
  10. case 3:
  11. echo '你好打工人,今天是工作日周三~';
  12. break;
  13. case 4:
  14. echo '你好打工人,今天是工作日周四~';
  15. break;
  16. case 5:
  17. echo '你好打工人,今天是工作日周五~';
  18. break;
  19. default :
  20. echo '打工人解放了,今天是周末~';
  21. }

2、循环流程控制

循环流程控制常见有三种:同样可参考 JS 中循环语法,具体可见https://www.php.cn/blog/detail/24740.html

  • while(){}入口判断型
  • do{}while();出口判断型 要记得在最后圆括号后面要加上分号,否则报错。
  • for(循环变量初始值;循环条件;循环变化){}计数型 最常见的循环

补充: 在上面我的 JS 文章中,将 forEach、for…in 和 for…of 也是纳入循环流程,有时感觉不适合,现在终于想明白了。这三者是 遍历 , 循环可以实现遍历,但遍历不是循环

  1. $cities = ['合肥','南京','杭州','苏州','上海'];
  2. //入口判断型
  3. while($city = current($cities))
  4. {
  5. echo $city,'<br>';
  6. //后移指针
  7. next($cities);
  8. }
  9. //指针复位
  10. reset($cities);
  11. // 出口判断型
  12. do{
  13. echo $city,'<br>';
  14. next($cities);
  15. //循环体内必须要有更新循环条件的语句,否则会进入死循环~
  16. }while($city = current($cities));
  17. //for循环
  18. for($i=0;$i<count($cities);$i++)
  19. {
  20. //输出拦截,break 提前结束循环
  21. if($i>2) break;
  22. echo $cities[$i],'<br>';
  23. }

3、PHP模板语法

在上面if多向分支中有大量的大括号{},这个若是在真实项目中将占用不少空间,最重要是阅读难度大,另外在Html中混合PHP条件控制时,大括号也增加阅读和编写难度。所以PHP对此类{}有了简化方案: 左大括号使用 冒号: 替换,右大括号使用 end关键字加分号 结束,二者之间的{}可直接简写成冒号:,右大括号可忽略。 如下面源码,测试完全正常

  1. <?php
  2. $hour = date("H");
  3. if ($hour < 6):
  4. echo '凌晨好,主人~';
  5. echo '凌晨好,主人~';
  6. elseif ($hour < 9):
  7. echo '早上好,主人~';
  8. echo '早上好,主人~';
  9. elseif ($hour < 12):
  10. echo '中午好,主人~';
  11. echo '中午好,主人~';
  12. elseif ($hour < 17):
  13. echo '下午好,主人~';
  14. echo '下午好,主人~';
  15. elseif ($hour < 19):
  16. echo '傍晚好,主人~';
  17. echo '傍晚好,主人~';
  18. elseif ($hour < 22):
  19. echo '晚上好,主人~';
  20. echo '晚上好,主人~';
  21. else:
  22. echo '别熬夜了!你头发没了~';
  23. echo '别熬夜了!你头发没了~';
  24. endif;

上面代码相对于大量{}的原始书写,无论是代码量,还是可阅读性都优秀不少,以后都将采用此类写法了,目前经常看到有if、switch、for和foreach都支持这种,后来据老师反馈,除了do…while外,基本都支持了。再看下老师用这种写法书写的前端混合代码:

  1. <?php if(!empty($_GET['name'])):?>
  2. <font color="red">非空的</font>
  3. <div><p>你好</p></div>
  4. <?php endif; ?>

五、学习后的总结

本来老师还要求用条件分支和运算符模拟计算器功能,这个我就不演示了,如果单纯的演示比较简单,我就写代码了。但是有几点可以和大家分享下:

  • 不要放过每次报错的解决机会,先自己测试解决,不行再百度,这样知识就会理解越深,掌握越牢,慢慢就转为技能了。
  • PHP和JS对单引号、双引号和反单引号的不同处理方式,值得注意。
  • PHP的模板语法对代码量减少和提高可阅读性都很有用,值得使用。
Correcting teacher:灭绝师太灭绝师太

Correction status:qualified

Teacher's comments:
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
2 comments
吾逍遥 2020-11-20 14:41:11
受教了,我对知识的探讨又超前了
2 floor
灭绝师太 2020-11-20 14:23:21
学习后的总结说的很有道理~很多初学者依赖别人解决问题,熟不知以后的码农生涯多数要自己解决,另外单引号,双引号,以及定界符是在之后的字符串函数库章节展开讲的~
1 floor
Author's latest blog post