php开发中的实际问题_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.'
';

}

echo $value.'
';

foreach($test as $value){

echo $value.'
';

}

echo $value;

解释

在第一个foreach中,我们使用了赋值引用符号,它的意思是每次遍历时,

math?formula=value%E6%8C%87%E5%90%91%E7%9A%84%E6%98%AFtest数组中的对应元素的地址,循环第一次时,

math?formula=value%E6%8C%87%E5%90%91%E7%9A%84%E6%98%AF'a'%E7%9A%84%E5%9C%B0%E5%9D%80%EF%BC%8C%E7%AC%AC%E4%BA%8C%E6%AC%A1%E5%BE%AA%E7%8E%AF%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8Cvalue指向的是第二个元素'b'的地址, 第三次循环时,

math?formula=value%E6%8C%87%E5%90%91%E7%9A%84%E5%B0%B1%E6%98%AF'c'%E7%9A%84%E5%9C%B0%E5%9D%80%E3%80%82%E5%BD%93%E6%88%91%E4%BB%AC%E5%9C%A8%E5%81%9A%E7%AC%AC%E4%BA%8C%E6%AC%A1%E9%81%8D%E5%8E%86%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E5%85%B6%E5%AE%9Evalue变量指向的还是

math?formula=test%E7%9A%84%E7%AC%AC%E4%B8%89%E4%B8%AA%E5%85%83%E7%B4%A0%E5%8D%B3'c'%E7%9A%84%E5%9C%B0%E5%9D%80%E3%80%82%E7%84%B6%E5%90%8Eforeach%E6%9C%AC%E8%BA%AB%E7%9A%84%E6%93%8D%E4%BD%9C%E6%98%AF%E6%8A%8A%E6%95%B0%E7%BB%84%E4%B8%AD%E5%AF%B9%E5%BA%94%E7%9A%84%E5%85%83%E7%B4%A0%E8%B5%8B%E5%80%BC%E7%BB%99as%E5%90%8E%E9%9D%A2%E7%9A%84%E5%8F%98%E9%87%8F%EF%BC%8C%E6%89%80%E4%BB%A5%E5%9C%A8%E7%AC%AC%E4%BA%8C%E4%B8%AAforeach%E4%B8%AD%EF%BC%8C%20%E9%81%8D%E5%8E%86%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E6%8A%8A'a'%E8%B5%8B%E5%80%BC%E7%BB%99value指向的地址(&

math?formula=test%5B2%5D)%EF%BC%8C%E5%8E%9F%E6%9C%89'c'%E6%89%80%E5%8D%A0%E7%9A%84%E5%9C%B0%E5%9D%80%E7%A9%BA%E9%97%B4%E7%9A%84%E5%80%BC%E5%8F%98%E4%B8%BA%E4%BA%86'a'%2C%E5%8D%B3%5B'a'%2C'b'%2C'a'%5D%EF%BC%8C%20%E7%AC%AC%E4%BA%8C%E6%AC%A1%E9%81%8D%E5%8E%86%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E6%8A%8A'b'%E8%B5%8B%E5%80%BC%E7%BB%99value指向的地址即['a','b','b'], 第三次遍历的时候,就把'b'赋值给$value指向的地址,最终结果['a','b','b']的原因。

解决方案

在使用完赋值引用操作符之后,把变量unset掉,上例中加上unset(

math?formula=value)%E8%AF%AD%E5%8F%A5%EF%BC%8C%E7%9B%B8%E5%BD%93%E4%BA%8E%E5%8F%96%E6%B6%88value对该地址的引用,这样第二次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

解释

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

解决方案

试用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取代之。

math?formula=a%20%3D%2021474836470%3B%20%E7%9C%8B%E4%B8%8A%E5%8E%BB%E6%98%AF%E6%95%B4%E6%95%B0%EF%BC%8C%E5%AE%9E%E9%99%85%E6%98%AF%E6%B5%AE%E7%82%B9%E6%95%B0%EF%BC%9Ba = 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

因"="的优先级低于"||",所以先逻辑判断再赋值。也就是(

math?formula=a%20%3D%20(5%20%7C%7Cb = 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

$a = '123';

?>

//file2.php

echo include('file1.php'); //1

?>

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

七、static和++

$count = 5;

function get_count() {

static $count = 0;

return $count++;

}

++$count;

echo $count; //6

echo get_count(); //0

echo get_count(); //1

?>

因static

math?formula=count%EF%BC%8C%E6%89%80%E4%BB%A5%E5%8F%AA%E5%9C%A8%E7%AC%AC%E4%B8%80%E6%AC%A1%E8%B0%83%E7%94%A8get_count%E7%9A%84%E6%97%B6%E5%80%99%E5%AF%B9count赋值为0,第二次再进来这个函数,则不会第二次赋值。其次就是return

math?formula=count%2B%2B%E5%92%8Creturn%20%2B%2Bcount了,前者先返回,后者先++再返回。

八、类型转换

$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了

十、++和&

$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了。其中注意的是&,如果有&则是对原变量操作,如果没有,则是先生成一个新变量,然后给这个变量复制,最后操作的是这个新变量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值