PHP8.0
发布 [1]也有一段时间了,此次发布带来了很多实用且强大的功能,比如:
Named arguments
1 2 3 4 5 htmlspecialchars ($string , ENT_COMPAT | ENT_HTML401, 'UTF-8' , false );htmlspecialchars ($string , double_encode : false );
传递参数时,可以通过指定参数名传递。
Constructor property promotion
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Point { public float $x ; public float $y ; public float $z ; public function __construct ( float $x = 0.0 , float $y = 0.0 , float $z = 0.0 ) { $this ->x = $x ; $this ->y = $y ; $this ->z = $z ; } } class Point { public function __construct ( public float $x = 0.0 , public float $y = 0.0 , public float $z = 0.0 , ) {}}
构造器参数向上提升,这个还挺有意思的,构造器中的参数(公众号 正义的程序 猿)直接变成了类的属性,大大简化了代码量。
Union types
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Number { private $number ; public function __construct ($number ) { $this ->number = $number ; } } new Number ('NaN' ); class Number { public function __construct ( private int |float $number ) {}} new Number ('NaN' );
在之前的版本,申明联合变量类型都是通(公众号 正义的程序猿)过注解的方式,而在8.0中,结合构造函数变量提升,直接在定义的时候申明联合类型,并且在8.0中是严格的,类型不匹配直接在运行时报错。
当然,8.0中的feature不止这些,还有很多。这里来详细说一下Saner string to number comparisons
,就是本文的标题。
现象
PHP中在比较时,我们经常这样操作:
结果符合我们的预期,但这样并不是每次都正确,比如:
1 2 3 4 5 0 == 'foobar' 0 == 'foobar'
是不是很诡异?
再来一个:
1 2 3 4 5 var_dump (in_array (0 , ['foo' , 'bar' ])); var_dump (in_array (0 , ['foo' , 'bar' ]));
还有:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $v = 0 ;switch ($v ) { case 'bar' : echo 'baaar' . PHP_EOL; case 0 : echo 'foo' . PHP_EOL; }
为什么
先来说一下PHP中的比较运算,分为两类,严格类型(===
,!==
)和非严格类型(==
, !=
, >
, >=
, 两者的主要区别如下:
严格类型比较底层用的是strcmp()
,非严格类型使用的是所谓的“智能”比较,即将字符串转为数字对比
在比较数组时,严格类型不光会比较值
,还会比较索引
的顺序,非严格类型只会简单的比较值
在比较对象时,严格类型使用对象标识符比较,非严格类型只会比较对象的值
在使用==
比较数字 和字符串 时,PHP 8.0之前的版本会先将字符串 转换为数字 ,之后再做两个数字间的比较,这也就是为什么上门0 == "foobar" = true
了。
Saner string to number comparisons
文章标题说PHP8中字符串与数字的比较更智能,具体智能在哪里?针对上面的问题,8.0当中引入Saner string to number comparisons
这个特性[2],底层具体的操作为:当比较数字字符 时,使用数字与数字对比,而其他字符与数字 比较时,统一使用字符串比较。我们来通过一个表格来对比下前后的变化:
1 2 3 4 5 6 7 8 Comparison | Before | After ------------------------------ 0 == "0" | true | true 0 == "0.0" | true | true 0 == "foo" | true | false 0 == "" | true | false 42 == " 42" | true | true 42 == "42foo" | true | false
参考:
https://www.php.net/releases/8.0/index.php
https://wiki.php.net/rfc/string_to_number_comparison