PHP开发中的坑

一、md5和sha1的0e...的问题

$md5_1 = md5('240610708');
$md5_2 = md5('QNKCDZO');

var_dump($md5_1);
var_dump($md5_2);

var_dump($md5_1 == $md5_2);

$sha_1 = sha1('aaO8zKZF');
$sha_2 = sha1('aa3OFF9m');

 var_dump($sha_1);
 var_dump($sha_2);

var_dump($sha_1 == $sha_2);

var_dump('0x1234Ab' == '1193131');

var_dump( 0 == "a" ); //true
var_dump( "0" == "a" ); //false

解释

由于 PHP 是弱类型语言,在使用 == 号时,如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行;两个字符串恰好以 0e 的科学记数法开头,字符串被隐式转换为浮点数,实际上也就等效于 0×10^0 ,因此比较起来是相等的

解决方案

PHP中的Hash校验,应该使用===,而不应该使用==。另外如果生产环境版本足够高的话(PHP >= 5.6.0),最好使用 hash_equals() 函数。

二、数组返回null的函数

error_reporting(0);

error_reporting(0);

$arr = [];

var_dump(trim($arr) === null); //true

var_dump(md5($arr) === null); //true

var_dump(explode(',', $arr) === null); //true

var_dump(strpos($arr, 'a')); //NULL  查找字符串首次出现的位置

var_dump(strcmp($arr, 'a')); //NULL  二进制安全字符串比较

三、foreach的引用与赋值

$test=array('a','b','c');
foreach($test as &$value){
    echo $value.'<br>';
}
echo $value.'<br>';

foreach($test as $value){
    echo $value.'<br>';
}
echo $value;
解释

在第一个foreach中,我们使用了赋值引用符号,它的意思是每次遍历时,value指向的是test数组中的对应元素的地址,循环第一次时,value指向的是'a'的地址,第二次循环的时候,value指向的是第二个元素'b'的地址, 第三次循环时,value指向的就是'c'的地址。当我们在做第二次遍历的时候,其实value变量指向的还是test的第三个元素即'c'的地址。然后foreach本身的操作是把数组中对应的元素赋值给as后面的变量,所以在第二个foreach中, 遍历第一次的时候,把'a'赋值给value指向的地址(&test[2]),原有'c'所占的地址空间的值变为了'a',即['a','b','a'], 第二次遍历的时候,把'b'赋值给value指向的地址即['a','b','b'], 第三次遍历的时候,就把'b'赋值给$value指向的地址,最终结果['a','b','b']的原因。

解决方案

在使用完赋值引用操作符之后,把变量unset掉,上例中加上unset(value)语句,相当于取消value对该地址的引用,这样第二次foreach的时候,$value相当于新的变量,不会导致上述问题。这也是一个很好的编程习惯。

四、精度问题

var_dump((0.1 + 0.7) === 0.8);//boolean false
var_dump((0.1 + 0.7) * 10 === 0.8 * 10);//boolean false
var_dump((0.1 + 0.7) * 100 === 0.8 * 100);//boolean true
echo intval(0.58 * 100);//57
echo intval(0.58 * 1000);//580


PHP浮点数的一个常见问题的解答

解释

不要用浮点数进行比较和数学运算转化为整型运算

解决方案

试用bcmath库(php自带)

四、整型溢出

$a = intval(21474836478);
var_dump($a);
$b = intval(2570);
$c = intval(21474839050);
var_dump($b === $c);

解释

PHP的整型数的字长和平台有关,对于32位的操作系统,最大的整型是2147483647(2^31),最小为 -2^31。可以表示4294967296个数字,有符号的话就是-2147483647到2147483648

解决方案

php里的办法就是:不能使用intval,用floatval取代之。
a = 21474836470; 看上去是整数,实际是浮点数;a = floatval(21474836470 ) 确保是一个数字

五、优先级

echo -10%3; // -1

因为-的优先级比%求余的优先级低,也就是-(10%3)。

ini_set('display_errors',0);
$arr = array(1=>1,3=>3);
$i = 2;
$a = 'test' . isset($arr[$i]) ? $arr[$i] : $i; //null

因"."的优先级高于三元运算符"?:"。所以程序其实报错了。会说$arr的索引2不存在。

$a = 3;
$b = 5;
if($a = 5 || $b = 7) {
    $a++;
    $b++;
}
echo $a . " " . $b;  // 1 6

因"="的优先级低于"||",所以先逻辑判断再赋值。也就是(a = (5 ||b = 7))。所以,最后其实给a赋值true了,$a等于1.

$x = 2;
echo $x == 2 ? '我' : $x == 1 ? '你' : '它'; //你

因为 == 的优先级比三元运算符高

$x = 2;//将2赋值给变量x 
echo true ? '我' : false ? '你' : '它';
//由于三元运算符左结合的特性 所以如上代码等效于
echo (true ? '我' : false) ? '你' : '它';
//先计算左边括号里的
echo '我' ? '你' : '它';

因"=="的优先级高于"?:"

六、include

//file1.php
<?php
$a = '123';
?>
//file2.php
<?php
echo include('file1.php'); //1
?>

因include()也是一个函数,有返回值。在成功时返回1,失败时返回错误信息。如果被包含的文件有return,则inculde()成功时返回该文件的返回值。

七、static和++

<?php
$count = 5;
function get_count() {
    static $count = 0;
    return $count++;
}
++$count;
echo $count; //6
echo get_count(); //0
echo get_count(); //1
?>

因static count,所以只在第一次调用get_count的时候对count赋值为0,第二次再进来这个函数,则不会第二次赋值。其次就是return count++和return ++count了,前者先返回,后者先++再返回。

八、类型转换

<?php
$arr = array(0 =>1,'aa' => 2,3,4);
foreach($arr as $key => $val){
    print($key == 'aa' ? 5 : $val);
}
//5534
?>

因遍历数组第一次的时候,$key和aa的比较实际就是0和aa的比较,一个是int一个是string,这个时候会转换类型,将字符串转换为数字再与数字比较。所以0=='aa'就是0==0,所以为true,也就是输出5。

九、count的用法

echo count (false); //1
$a = count ("567")  + count(null) + count(false);
echo $a;//2

如果不是数组或者对象的其他类型,返回1.那么这个值应该就是1+0+1了

十、++和&

<?php

$arr = array(1,2,3);
foreach($arr as &$val) {
    echo $val % 2; //1,0,1
    $val += $val % 2 ? $val++ : $val--;
}
print_r($arr);
$val = 0;
print(join('',$arr));

//101Array ( [0] => 3 [1] => 3 [2] => 7 ) 330
?>

因foreach结束后的数组应该是array(3,3,7);最后给第三个元素赋值为0,所以就是330了。其中注意的是&,如果有&则是对原变量操作,如果没有,则是先生成一个新变量,然后给这个变量复制,最后操作的是这个新变量。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,423评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,147评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,019评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,443评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,535评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,798评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,941评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,704评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,152评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,494评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,629评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,295评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,901评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,978评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,333评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,499评论 2 348

推荐阅读更多精彩内容

  • 一、php可以做什么 php是一种可以在服务器端运行的编程语言,可以运行在Web服务器端。 php是一门后台编程语...
    空谷悠阅读 3,088评论 4 97
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,763评论 0 38
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,725评论 0 10
  • 《裕语言》速成开发手册3.0 官方用户交流:iApp开发交流(1) 239547050iApp开发交流(2) 10...
    叶染柒丶阅读 26,264评论 5 19
  • 在中国当大领导真难:必须懂权衡,要不然很难稳定,正反俩派才能维持稳定,但这种稳定往往阻碍创新,阻碍变革,没有变革就...
    54f70f613c7c阅读 175评论 1 2