PHP的编程细节

自增自减运算


++,–,这玩意在以前学校考试的时候用的多,正常使用情况在循环时用。

1
2
3
4
5
$a = 1;
echo $a+$a++;  //3
 
$a = 2;
echo $a+$a+$a++; //3

这个大家可以自己亲测下,两者都是3。要想搞懂原理就要看php对它的实现了,看看opcode的执行。
自增自减运算还是慎用吧,能不用就不用,免得给自己徒增烦恼,像现在的python、ruby就直接抛弃了对它的支持。

三目运算

1
2
3
$a = 2;
$b = 3;
echo $b?$b:0 - $a?$a:0; //2

这个其实也考虑到优先级的,肯定很多人习惯,或者想当然是先算好减号左边,再算好减号右边,然后相减得到1(我是亲身经历过,然后找bug找了好久).
但实际它输出2,因为php是左结合:($b?$b:0-$a)?$a:0;
用其他语言javascript、c试过,均输出3,他们是右结合:$b?$b:(0-$a?$a:0);

浮点型运算

1
2
3
$f = 0.58;
var_dump(intval($f * 100));
//输出:57

这个具体解释,详见鸟哥博客: PHP浮点数的一个常见问题的解答

1
2
3
4
5
$a = 134.7;
$b = 52.5;
$c = 82.2;
echo $a - $b - $c;
//输出:-1.4210854715202E-14

其实跟上面是一类的问题,那如果我真的就要拿php来做小数运算呢?可以,提供了BCMATH(参考手册)相关函数,上面的可以写成:

1
2
echo bcsub(bcsub($a,$b,1),$c,1);
//输出:0.0

不过BCMATH是当成字符串来处理的,返回值是一个string

switch语句机制

switch语句大家都在用,但肯定不是所有人都知道它在编辑器中的运行机制,这就导致写出一些不同寻常的switch语句来,可能大家无法理解,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$temp = 10;
switch($temp)
{
    default:
        echo '未匹配到';
    case 8:
        echo '8';break;
    case 9:
        echo '9';break;
}
//输出:未匹配到8
 
switch($temp)
{
    default:
        echo '未匹配到';
    case 8:
        echo '8';break;
    case 9:
        echo '9';break;
    case 10:
        echo '10';break;
}
//输出:10

应该很少见到吧default写在第一行吧,虽然意外,但这样写确实正确,跟写在最后效果是一样的(前提是你在每个case、default后都跟上break)。
总结下:
一、switch不会在每个case标签后面的语句执行完毕后自动终止。switch只执行一次匹配,然后往下执行,直到break为止,就是说一旦执行某个case语句,程序将会一次执行后面所有的case,除非遇到break语句。
二、各个case和default顺序可以是任意的,如果没有default,而且每个case选项都不符合,则相当于switch语句没有执行。
这样,上面两个例子的输出应该好理解了,如果要深层次的了解switch机制,这得要去汇编分析了。

循环内部变量

1
2
3
4
5
6
7
8
9
10
11
12
13
$data = array(5,4,3,2,1);
if (is_array($data)) foreach($data as $k => $v)
{
    if ( $v > 2 )
    {
        $temp = true;
    }
    if ( $temp )
    {
        echo $v.',';
    }
}
//输出: 5,4,3,2,1,

例子有点简单,就是打印出数组中大于2的数,结果发现整个数组都打印了。
这就涉及到循环内部变量处理了,因为foreach循环本身不是完整的一块作用域,所有内部定义的$temp变量在循环外也还有效。当遍历到3的时候,$temp = true,接着遍历到2,if不满足,但此时$temp还是true,下面的输出照样执行。
处理办法:
一、内部变量都要初始化,这里在foreach的第一行加上:$temp = false;
二、重构,如果foreach内部代码过于复杂,可以考虑重构,提炼函数,函数是一个完整的作用域,就不用担心内部变量问题了。
这类错误看似简单,有时候犯下了,找bug很难发现,在复杂逻辑情况下,肯定优先考虑会不会是逻辑出了问题,从而忽略了这些小地方。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值