常言道常在河边走,哪能不湿鞋。作为天天写php的老司机,时不时就会被php的某个特性给坑一下。周末整理了三个自己或者身边朋友碰到的最坑爹的case,分享给大家。
一、为啥接口偶尔会报签名错误呢?
做过接口开发的phper都知道,往往为了安全性,接口都会增加一个签名字段,用来保证安全。但是,如果一个运行良好的接口,就是有不那么高的概率报签名错误,到底是怎么回事呢?
这是我实际碰到的一个case,我们在调用其它服务时,有时会出现签名错误的错误码。这个事情很诡异。因为我们的签名是用传递的参数加上秘钥md5得到的,接收方也是一样的方式来校验。我们算签名是发送前的最后一步,算完签名就扔给接收方了。如果签名要是错了,那肯定就是算法错了。可是这种一会对一会错的,到底算个啥?
后来我们在发送方和接收方都打了日志,好不容易又出现了这个case,赶紧拉出来分析。不看不知道,看了气吐血。看看下面这个图:
是的,你应该猜到了。在我们发送方计算的时候,由于是使用字符串连接来做的加密串计算,所以会有x等于空字符串,y等于空字符串来参与计算签名。而发给接收方的时候,经过了一道http_build_query,接收方收到了一个为0的x,而且没有收到y。签名算出来自然不对了。
由于生成的参数值偶尔会有false或者null这种值,所以签名会偶尔报错。我有理由相信,很多经验丰富的老司机,开到这里都会栽一下。如果不小心栽在某个重要接口上,真心是浑身有嘴都说不清。
二、奇怪了,不是有值吗?怎么empty是true?
这个case是我朋友的,但是丝毫不影响我把它放在这篇分享坑爹case的文章里。首先看看下面的代码及结果:
神奇吧?猜猜看,为啥?
好,可能你有个猜想,不过我们先看看class a的定义。
事实上,是因为empty里面有个isset的判断,自然class a没有x这个属性,所以empty就返回了true。在这个代码里面,这个问题倒是很简单。可是实际开发中,很多框架或者自己的代码都会使用__get,到时候判断的时候,任你多少年的老司机,稍微一不注意,车轮就进来了。这种bug可是bool的颠倒,完全改变了后续的逻辑,想想就知道多恐怖。
三、咦?配置文件报错?
最后来个专坑老司机的。老司机到了一定层次,会自己写一些会手动载入配置的代码,比如下面这个db的示例。
很熟悉对不对,粗看没有问题对不对。可是你发现这货跑着跑着会报错。你去review也找不到问题点。var_dump加上exit吧,也没啥问题。郁闷死了对不对。
这个示例代码很短,而且明确的指出了可能出问题的地方,相信大家都找到了问题所在:第二次实例化DB的时候,载入的config是true,而不是数组。这是因为require_once在第二次载入同一个文件的时候,就会直接返回true了。
对于这种第二次才犯病的bug,如果一开始不出现,这个雷就潜伏了下来。而且这种代码可能一般是很基础的很底层的代码,说不好某个时候你就写了个正常的代码,这雷就炸了,而且还炸在另一个毫无关联的地方。
祝大家好好开车,争做平平安安的好司机。