zoukankan      html  css  js  c++  java
  • PHP开发中常见的坑

    PHP开发中常见的坑

    1、switch/case

    使用 switch 语句可以避免冗长的 if..elseif..else 代码块。但是一不小心,就会掉坑里。

    1)当case为一个范围时
    使用 0 < $num < 50,这种方式是不可以的,所以要用 0 < $num && $num < 50的方式,拆开写才可以

     1 <?php
     2 $a = 89;
     3 switch ($a) {
     4     case ($a < 60):
     5         echo '不及格';
     6         break;
     7     case ($a < 80):
     8         echo '中等';
     9         break;
    10     case ($a < 90):
    11         echo '良';
    12         break;
    13     default:
    14         echo '优秀';
    15         break;
    16 }
    17 
    18 // 输出结果
    19 // 良

    2)当switch表达式中的值为0

     1 <?php
     2 $a = 0;
     3 switch ($a) {
     4     case ($a < 60):
     5         echo '不及格';
     6         break;
     7     case ($a < 80):
     8         echo '中等';
     9         break;
    10     case ($a < 90):
    11         echo '良';
    12         break;
    13     default:
    14         echo '优秀';
    15         break;
    16 }
    17 // 输出结果
    18 // 优秀

    这个地方,如果按照if...else的思维,满足第一个case语句,然后直接输出:不及格。但是实际情况输出的是:优秀

    分析:switch/case跟if...else条件语句的区别是,switch表达式的值是与case语句中的值作匹配的,并不是像if条件中的只要是true就执行

    php里面的switch会转换case类型,使用的时候一定要注意。

    3)switch/case作的是松散比较

     1 <?php
     2 $string = "2string";
     3 
     4 switch ($string) {
     5     case 1:
     6         echo "this is 1";
     7         break;
     8     case 2:
     9         echo "this is 2";
    10         break;
    11     case '2string':
    12         echo "this is a string";
    13         break;
    14 }
    15 
    16 // 输出结果
    17 // this is 2

    注意:

       1) switch中使用“==”进行比较的时候,尤其是string和int值比较时,会将字符串强转为int类型

       2) 在使用switch的时候,应该保证比较值和每个case的类型一致,否则就可能出现不可预计的错误

    2、in_array

    bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
    说明:在 haystack 中搜索 needle,如果没有设置 strict 则使用 宽松 的比较。如果第三个参数 strict 的值为 true,则 in_array 函数还会检查 needle 的 类型 是否和 haystack 中的相同。

     1 <?php
     2 
     3 $arr = [0, 1];
     4 $a = '1test';
     5 if (in_array($a, $arr)) {
     6     echo 111;
     7 } else {
     8     echo 222;
     9 }
    10 
    11 // 输出结果
    12 // 111

    可以看到,这里$a = ‘1test’,在校验过程中,$a由字符串转成了int类型,绕过了in_array中的校验。

    解决方法有三种:

    1)将参数$a类型转换成整型: $a=(int)$a;

    2)in_array中的数组内value改成字符串类型:in_array($a,['1','2'])

    3)in_array中第三个参数 strict 的值设为 true:in_array($a,[1,2],true)

     1 <?php
     2 
     3 $arr = [0, 1];
     4 $a = '1a';
     5 if (in_array($a, $arr,true)) {
     6     echo 111;
     7 } else {
     8     echo 222;
     9 }
    10 
    11 // 输出结果
    12 // 222

    另外,补充一下,关于字符串/字符和数字进行大小比较时,会将字符串转成数字,

    1)PHP 8.0 之前,首先系统尝试将此字符串/字符转换为整型/浮点型,然后进行比较,如'12bsd'转型为12,'a'转型为0

    2)PHP 8.0 比较数字字符串(numeric string)时,会按数字进行比较。 不是数字字符串时,将数字转化为字符串,按字符串比较。

    1 <?php
    2 
    3 // PHP 7
    4 0 == 'foobar'; // true
    5 
    6 // PHP 8
    7 0 == 'foobar';// false

    3、关于if else容易迷惑的问题

     1 <?php
     2 $a = true;
     3 if ($a) {
     4     echo "true".PHP_EOL;
     5 } else label: {
     6     echo "false";
     7 }
     8 
     9 // 输出结果
    10 // true
    11 // false

    在zend_language_parser.y中:

    1 statement:
    2 ...
    3 | T_DO statement T_WHILE '(' expr ')' ';' {...}
    4 | T_SWITCH '(' expr ')' switch_case_list {...}
    5 | T_STRING ‘:’ { $$ = zend_ast_create(ZEND_AST_LABEL, $1); } 

     这里可以看到,do while, switch 都会联合他们的body归约为statement(语句),但标签(label)有点不同,”label :”本身会归约为一条statement, 这就导致了这个看起来比较迷惑的问题的出现,他本质上就变成了:

     1 <?php
     2 $a = true;
     3 if ($a) {
     4     echo "true".PHP_EOL;
     5 } else {
     6     label: ;  //单独的一条语句
     7 }
     8 echo "false";
     9 
    10 // 输出结果
    11 // true
    12 // false

    参考链接:https://www.laruence.com/2020/07/09/6015.html

  • 相关阅读:
    编程为谁?
    Nokia S60编程环境的建立(转自彩酷玩家)
    你可以是一个机器吗?
    无法在web服务器上启动调试的解决
    VB.NET和VB6.0有什么区别(转)
    短信3
    短信2
    短信(转自天极)
    短信4
    函数递归调用
  • 原文地址:https://www.cnblogs.com/hld123/p/14332029.html
Copyright © 2011-2022 走看看