资讯专栏INFORMATION COLUMN

PHP 7.1 新特性一览

timger / 971人阅读

摘要:版本发布在即,本文整理一下中的一些新特性以供了解。所有内容均选自官方文档。可空类型可空类型主要用于参数类型声明和函数返回值声明。主要的两种形式如下从例子很容易理解,所指的就是通过的形式表明函数参数或者返回值的类型要么为指定类型,要么为。

PHP 7.1 release版本发布在即,本文整理一下 7.1 中的一些新特性以供了解。所有内容均选自官方 RFC 文档。

可空类型

可空类型主要用于参数类型声明和函数返回值声明。

主要的两种形式如下:

function answer(): ?int  {
    return null; //ok
}
 
function answer(): ?int  {
    return 42; // ok
}

function say(?string $msg) {
    if ($msg) {
        echo $msg;
    }
}

从例子很容易理解,所指的就是通过 ? 的形式表明函数参数或者返回值的类型要么为指定类型,要么为 null

此方法也可用于接口函数的定义:

interface Fooable {
    function foo(?Fooable $f);
}

但有一个需要注意的地方:如果函数本身定义了参数类型并且没有默认值,即使是可空的,也不能省略,否则会触发错误。如下:

function foo_nullable(?Bar $bar) {}
 
foo_nullable(new Bar); // 可行
foo_nullable(null); // 可行
foo_nullable(); // 不可行

但是如果以上函数的参数定义为 ?Bar $bar = null 的形式,则第三种写法也是可行的。因为 = null 实际上相当于 ? 的超集,对于可空类型的参数,可以设定 null 为默认值。

list 的方括号简写

我们知道在 PHP5.4 之前只能通过 array() 来定义数组,5.4之后添加了 [] 的简化写法(省略了5个字符还是很实在的)。

// 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 来实现:

list($a, $b, $c) = $array;

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

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

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

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

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

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

foreach ($points as ["x" => $x, "y" => $y]) {
    var_dump($x, $y);
}

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

// 不合法
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

上文提到过,新的 list() 的实现中可以指定key:

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

这也就相当于:

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

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

list($a, $b) = [1 => "1", 2 => "2"];

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

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

list(1 => $a, 2 => $b) = [1 => "1", 2 => "2"];

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

// Parse error: syntax error, ...
list($unkeyed, "key" => $keyed) = $array;

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

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

以及循环中使用:

$points = [
    ["x" => 1, "y" => 2],
    ["x" => 2, "y" => 1]
];
 
foreach ($points as list("x" => $x, "y" => $y)) {
    echo "Point at ($x, $y)", PHP_EOL;
}
void 返回类型

PHP7.0 添加了指定函数返回类型的特性,但是返回类型却不能指定为 void,7.1 的这个特性算是一个补充:

function should_return_nothing(): void {
    return 1; // Fatal error: A void function must not return a value
}

以下两种情况都可以通过验证:

function lacks_return(): void {
    // valid
}

function returns_nothing(): void {
    return; // valid
}

定义返回类型为 void 的函数不能有返回值,即使返回 null 也不行:

function returns_one(): void {
    return 1; // Fatal error: A void function must not return a value
}

function returns_null(): void {
    return null; // Fatal error: A void function must not return a value
}

此外 void 也只适用于返回类型,并不能用于参数类型声明,或者会触发错误:

function foobar(void $foo) { // Fatal error: void cannot be used as a parameter type
}

类函数中对于返回类型的声明也不能被子类覆盖,否则会触发错误:

class Foo
{
    public function bar(): void {
    }
}
 
class Foobar extends Foo
{
    public function bar(): array { // Fatal error: Declaration of Foobar::bar() must be compatible with Foo::bar(): void
    }
}
类常量属性设定

这个特性说起来比较简单,就是现在类中的常量支持使用 publicprivateprotected 修饰了:

class Token {
    // 常量默认为 public
    const PUBLIC_CONST = 0;

    // 可以自定义常量的可见范围
    private const PRIVATE_CONST = 0;
    protected const PROTECTED_CONST = 0;
    public const PUBLIC_CONST_TWO = 0;
 
    // 多个常量同时声明只能有一个属性
    private const FOO = 1, BAR = 2;
}

此外,接口(interface)中的常量只能是 public 属性:

interface ICache {
    public const PUBLIC = 0;
    const IMPLICIT_PUBLIC = 1;
}

为了应对变化,反射类的实现也相应的丰富了一下,增加了 getReflectionConstantgetReflectionConstants 两个方法用于获取常量的额外属性:

class testClass  {
    const TEST_CONST = "test";
}
 
$obj = new ReflectionClass( "testClass" );
$const = $obj->getReflectionConstant( "TEST_CONST" );
$consts = $obj->getReflectionConstants();
多条件 catch

在以往的 try ... catch 语句中,每个 catch 只能设定一个条件判断:

try {
    // Some code...
} catch (ExceptionType1 $e) {
    // 处理 ExceptionType1
} catch (ExceptionType2 $e) {
    // 处理 ExceptionType2
} catch (Exception $e) {
    // ...
}

新的实现中可以在一个 catch 中设置多个条件,相当于或的形式判断:

try {
    // Some code...
} catch (ExceptionType1 | ExceptionType2 $e) {
    // 对于 ExceptionType1 和 ExceptionType2 的处理
} catch (Exception $e) {
    // ...
}

对于异常的处理简化了一些。

附:源 RFC 地址

Nullable Types

Square bracket syntax for array destructuring assignment

Allow specifying keys in list()

Generalize support of negative string offsets

Void Return Type

Class constant visibility modifiers

Multi catch

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30449.html

相关文章

  • PHP 7.0 & 7.1 部分特性备忘

    摘要:以下分别备忘版本的部分新增特性。而且,在生成器没有输出完全时,使用会报错。报错定义常量数组多声明数组解构运行时将部分指令转为机器码。对于计算密集型应用有较高的性能提升。 以下分别备忘 PHP 7.0 & 7.1 版本的部分新增特性。 PHP 7.0 ?? 运算符 $foo = null; $bar = $foo ?? 123; // 相当于 $bar = isset($bar) ? ...

    philadelphia 评论0 收藏0
  • 2017年3月份前端资源分享

    平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 03月份前端资源分享 1. Javascript 175453545 Redux compose and middleware 源码分析 深入 Promise(二)——进击的 Promise Effective JavaScript leeheys blog -...

    ermaoL 评论0 收藏0
  • 2017年3月份前端资源分享

    平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 03月份前端资源分享 1. Javascript 175453545 Redux compose and middleware 源码分析 深入 Promise(二)——进击的 Promise Effective JavaScript leeheys blog -...

    kamushin233 评论0 收藏0
  • 2017年3月份前端资源分享

    平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 03月份前端资源分享 1. Javascript 175453545 Redux compose and middleware 源码分析 深入 Promise(二)——进击的 Promise Effective JavaScript leeheys blog -...

    TNFE 评论0 收藏0
  • 2017年3月份前端资源分享

    平日学习接触过的网站积累,以每月的形式发布。2017年以前看这个网址:http://www.kancloud.cn/jsfron... 03月份前端资源分享 1. Javascript 175453545 Redux compose and middleware 源码分析 深入 Promise(二)——进击的 Promise Effective JavaScript leeheys blog -...

    yy736044583 评论0 收藏0

发表评论

0条评论

阅读需要支付1元查看
<