PHP7 的部分新特性

1. 运算符(NULL 合并运算符)

$a = $_GET['a'] ?? 1;

它相当于:

<php
$a = isset($_GET['a']) ? $_GET['a'] : 1;

我们知道三元运算符是可以这样用的:

$a ?: 1

但是这是建立在 $a 已经定义了的前提上。新增的 ?? 运算符可以简化判断。

 

2、List 的方括号简写

PHP5.4 之前只能通过 array() 来定义数组,5.4之后添加了 [] 的简化写法。

<?php // 5.4 之前

$array = array(1, 2, 3);

$array = array("a" => 1, "b" => 2, "c" => 3);

// 5.4 及之后

$array = [1, 2, 3];

$array = ["a" => 1, "b" => 2, "c" => 3];

那么,如果要把数组的值赋值给不同的变量,可以通过 list 来实现:

  <?php list($a, $b, $c) = $array;

是否也可以通过 [] 的简写来实现呢?

  <?php [$a, $b, $c] = $array;

 以及下一个特性中会提到的 list 指定 key:

 <?php ["a" => $a, "b" => $b, "c" => $c] = $array;

 

PHP7.1 实现了这个特性,但:出现在左侧的 [] 并不是数组的简写,而是 list() 的简写。

现在新的 list() 的实现并不仅仅可以出现在左值中,也能在 foreach 循环中使用: 

  <?php foreach ($points as ["x" => $x, "y" => $y]) {

      var_dump($x, $y);

  }

不过因为实现的问题,list() 和 [] 不能相互嵌套使用:

  <?php // 不合法

  list([$a, $b], [$c, $d]) = [[1, 2], [3, 4]];

  // 不合法

  [list($a, $b), list($c, $d)] = [[1, 2], [3, 4]];

  // 合法

  [[$a, $b], [$c, $d]] = [[1, 2], [3, 4]];

 

另外,在新的 list() 的实现中可以指定key:

  <?php $array = ["a" => 1, "b" => 2, "c" => 3];

  ["a" => $a, "b" => $b, "c" => $c] = $array;

相当于:

  <?php $a = $array['a'];

  $b = $array['b'];

  $c = $array['c'];

 

和以往的区别在于以往的 list() 的实现相当于 key 只能是 0, 1, 2, 3 的数字形式并且不能调整顺序。执行语句:

  <?php list($a, $b) = [1 => '1', 2 => '2'];

会得到 PHP error: Undefined offset: 0... 的错误。

 

新的实现则可以通过以下方式来调整赋值:

   <?php list(1 => $a, 2 => $b) = [1 => '1', 2 => '2'];

不同于数组的是,list 并不支持混合形式的 key,以下写法会触发解析错误:

<?php // Parse error: syntax error, ...

list($unkeyed, "key" => $keyed) = $array;

 

更复杂的情况,list 也支持复合形式的解析:

<?php $points = [

    ["x" => 1, "y" => 2],

    ["x" => 2, "y" => 1]

];

 

list(list("x" => $x1, "y" => $y1), list("x" => $x2, "y" => $y2)) = $points;

 

$points = [

    "first" => [1, 2],

    "second" => [2, 1]

];

 

list("first" => list($x1, $y1), "second" => list($x2, $y2)) = $points;

 

以及循环中使用:

<?php $points = [

    ["x" => 1, "y" => 2],

    ["x" => 2, "y" => 1]

];

 

foreach ($points as list("x" => $x, "y" => $y)) {

    echo "Point at ($x, $y)", PHP_EOL;

}

 

3. 标量类型和返回类型声明(Scalar Type Declarations & Scalar Type Declarations)

PHP语言一个非常重要的特点就是“弱类型”,它让PHP的程序变得非常容易编写,新手接触PHP能够快速上手。PHP 7 中的函数的形参类型声明可以是标量了。在 PHP 5 中只能是类名、接口、array 或者 callable (PHP 5.4,即可以是函数,包括匿名函数),现在也可以使用 string、int、float和 bool 了。支持变量类型的定义,可以说是革新性质的变化,PHP开始以可选的方式支持类型定义。除此之外,还引入了一个开关指令declare(strict_type=1);,当这个指令一旦开启,将会强制当前文件下的程序遵循严格的函数传参类型和返回类型。

例如一个add函数加上类型定义,可以写成这样:

如果配合强制类型开关指令,则可以变为这样:

如果不开启strict_type,PHP将会尝试帮你转换成要求的类型,而开启之后,会改变PHP就不再做类型转换,类型不匹配就会抛出错误。对于喜欢“强类型”语言的同学来说,这是一大福音。

需要注意的是严格模式的问题在这里同样适用:强制模式(默认,既强制类型转换)下还是会对不符合预期的参数进行强制类型转换,严格模式下则触发 TypeError 的致命错误。

 

4、 更多的Error变为可捕获的Exception

 

PHP7实现了一个全局的throwable接口,原来的Exception和部分Error都实现了这个接口(interface), 以接口的方式定义了异常的继承结构。于是,PHP7中更多的Error变为可捕获的Exception返回给开发者,如果不进行捕获则为Error,如果捕获就变为一个可在程序内处理的Exception。这些可被捕获的Error通常都是不会对程序造成致命伤害的Error,例如函数不存。PHP7进一步方便开发者处理,让开发者对程序的掌控能力更强。因为在默认情况下,Error会直接导致程序中断,而PHP7则提供捕获并且处理的能力,让程序继续执行下去,为程序员提供更灵活的选择。

 

例如,执行一个我们不确定是否存在的函数,PHP5兼容的做法是在函数被调用之前追加的判断function_exist,而PHP7则支持捕获Exception的处理方式。

5、AST(Abstract Syntax Tree,抽象语法树)

    AST在PHP编译过程作为一个中间件的角色,替换原来直接从解释器吐出opcode的方式,让解释器(parser)和编译器(compliler)解耦,可以减少一些Hack代码,同时,让实现更容易理解和可维护。

  PHP 5:

  

  PHP 7:

  

  更多AST信息:https://wiki.php.net/rfc/abstract_syntax_tree

6、其他新特性

PHP 7新特性和变化不少,我们这里并不全部展开来细说哈。

  1. Int64支持,统一不同平台下的整型长度,字符串和文件上传都支持大于2GB。
  2. 统一变量语法(Uniform variable syntax)。
  3. foreach表现行为一致(Consistently foreach behaviors)
  4. 新的操作符 <=>, ??
  5. Unicode字符格式支持(\u{xxxxx})
  6. 匿名类支持(Anonymous Class)

 

posted @ 2017-02-08 10:08  蚂蚁力量  阅读(3775)  评论(0编辑  收藏  举报