龙空技术网

PHP8中字符串与数字的比较更智能

程序员tb 315

前言:

此刻兄弟们对“phppoint”都比较讲究,各位老铁们都想要剖析一些“phppoint”的相关内容。那么小编在网摘上搜集了一些有关“phppoint””的相关文章,希望咱们能喜欢,各位老铁们快快来学习一下吧!

PHP8.0发布[1]也有一段时间了,此次发布带来了很多实用且强大的功能,比如:

Named arguments

// php 7.xhtmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);// php 8.0htmlspecialchars($string, double_encode: false);

传递参数时,可以通过指定参数名传递。

Constructor property promotion

// php 7.xclass 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;  }}// php 8.0class Point {  public function __construct(    public float $x = 0.0,    public float $y = 0.0,    public float $z = 0.0,  ) {}}

构造器参数向上提升,这个还挺有意思的,构造器中的参数(公众号 正义的程序猿)直接变成了类的属性,大大简化了代码量。

Union types

// php 7.xclass Number {  /** @var int|float */  private $number;  /**   * @param float|int $number   */  public function __construct($number) {    $this->number = $number;    // 公众号 正义的程序猿  }}new Number('NaN'); // Ok// php 8.0class Number {  public function __construct(    private int|float $number  ) {}}new Number('NaN'); // TypeError

在之前的版本,申明联合变量类型都是通(公众号 正义的程序猿)过注解的方式,而在8.0中,结合构造函数变量提升,直接在定义的时候申明联合类型,并且在8.0中是严格的,类型不匹配直接在运行时报错。

当然,8.0中的feature不止这些,还有很多。这里来详细说一下Saner string to number comparisons,就是本文的标题。

现象

PHP中在比较时,我们经常这样操作:

10 == '10'

结果符合我们的预期,但这样并不是每次都正确,比如:

// php 7.x0 == 'foobar' // true  // php 8.00 == 'foobar' // false

是不是很诡异?

再来一个:

// php 7.xvar_dump(in_array(0, ['foo', 'bar'])); // true// php 8.0var_dump(in_array(0, ['foo', 'bar'])); // false

还有:

// php 7.x$v = 0;switch ($v) {    case 'bar':        echo 'baaar' . PHP_EOL;    case 0:        echo 'foo' . PHP_EOL;}// 输出:// baaar// foo// PHP 8.0// 输出// foo
为什么

先来说一下PHP中的比较运算,分为两类,严格类型(===,!==)和非严格类型(==, !=, >, >=, 两者的主要区别如下:

严格类型比较底层用的是strcmp(),非严格类型使用的是所谓的“智能”比较,即将字符串转为数字对比在比较数组时,严格类型不光会比较,还会比较索引的顺序,非严格类型只会简单的比较值在比较对象时,严格类型使用对象标识符比较,非严格类型只会比较对象的值

在使用==比较数字和字符串时,PHP 8.0之前的版本会先将字符串转换为数字,之后再做两个数字间的比较,这也就是为什么上门0 == "foobar" = true了。

Saner string to number comparisons

文章标题说PHP8中字符串与数字的比较更智能,具体智能在哪里?针对上面的问题,8.0当中引入Saner string to number comparisons这个特性[2],底层具体的操作为:当比较数字字符时,使用数字与数字对比,而其他字符与数字比较时,统一使用字符串比较。我们来通过一个表格来对比下前后的变化:

Comparison    | Before | After------------------------------ 0 == "0"     | true   | true 0 == "0.0"   | true   | true 0 == "foo"   | true   | false 0 == ""      | true   | false42 == "   42" | true   | true42 == "42foo" | true   | false

如果喜欢,可以关注我哦~

参考:

标签: #phppoint