PHP 7.1新特性的汇总介绍

一、可空类型

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

主要的两种形式如下:

rush:PHP;"> PHP function answer(): ?int { return null; //ok }

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

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

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

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

rush:PHP;"> PHP interface Fooable { function foo(?Fooable $f); }

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

rush:PHP;"> PHP 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个字符还是很实在的)。

rush:PHP;"> 1,"b" => 2,"c" => 3);

// 5.4 及之后
$array = [1,3];
$array = ["a" => 1,"c" => 3];

引申到另外一个问题上,如果我们要把数组的值赋值给不同的变量,可以通过 list 来实现:

rush:PHP;"> PHP list($a,$b,$c) = $array;

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

rush:PHP;"> PHP [$a,$c] = $array;

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

rush:PHP;"> $a,"b" => $b,"c" => $c] = $array;

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

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

rush:PHP;"> $x,"y" => $y]) { var_dump($x,$y); }

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

rush:PHP;"> PHP // 不合法 list([$a,$b],[$c,$d]) = [[1,2],[3,4]];

// 不合法
[list($a,$b),list($c,$d)] = [[1,4]];

// 合法
[[$a,$d]] = [[1,4]];

三、允许在 list 中指定 key

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

rush:PHP;"> 1,"c" => 3]; ["a" => $a,"c" => $c] = $array;

这也就相当于:

rush:PHP;"> PHP $a = $array['a']; $b = $array['b']; $c = $array['c'];

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

rush:PHP;"> '1',2 => '2'];

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

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

rush:PHP;"> $a,2 => $b) = [1 => '1',2 => '2'];

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

rush:PHP;"> $keyed) = $array;

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

rush:PHP;"> 1,"y" => 2],["x" => 2,"y" => 1] ];

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

$points = [
"first" => [1,"second" => [2,1]
];

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

以及循环中使用:

rush:PHP;"> 1,"y" => 1] ];

foreach ($points as list("x" => $x,"y" => $y)) {
echo "Point at ($x,$y)",PHP_EOL;
}

四、void 返回类型

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

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

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

rush:PHP;"> PHP function lacks_return(): void { // valid }

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

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

rush:PHP;"> PHP 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 也只适用于返回类型,并不能用于参数类型声明,或者会触发错误

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

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

rush:PHP;"> PHP 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
}
}

五、类常量属性设定

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

rush:PHP;"> PHP 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 属性

rush:PHP;"> PHP interface ICache { public const PUBLIC = 0; const IMPLICIT_PUBLIC = 1; }

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

rush:PHP;"> $obj = new ReflectionClass( "testClass" );
$const = $obj->getReflectionConstant( "TEST_CONST" );
$consts = $obj->getReflectionConstants();

六、多条件 catch

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

rush:PHP;"> PHP try { // Some code... } catch (ExceptionType1 $e) { // 处理 ExceptionType1 } catch (ExceptionType2 $e) { // 处理 ExceptionType2 } catch (\Exception $e) { // ... }

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

rush:PHP;"> PHP try { // Some code... } catch (ExceptionType1 | ExceptionType2 $e) { // 对于 ExceptionType1 和 ExceptionType2 的处理 } catch (\Exception $e) { // ... }

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用PHP7.1能有一定的帮助,如果有疑问大家可以留言交流。

附:源 RFC 地址

nofollow" target="_blank" href="https://wiki.PHP.net/rfc/multiple-catch">Multi catch

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


服务器优化必备:深入了解PHP8底层开发原理
Golang的网络编程:如何快速构建高性能的网络应用?
Golang和其他编程语言的对比:为什么它的开发效率更高?
PHP8底层开发原理揭秘:如何利用新特性创建出色的Web应用
将字符重新排列以形成回文(如果可能)在C++中
掌握PHP8底层开发原理和新特性:创建高效可扩展的应用程序
服务器性能优化必学:掌握PHP8底层开发原理
PHP8新特性和底层开发原理详解:优化应用性能的终极指南
将 C/C++ 代码转换为汇编语言
深入研究PHP8底层开发原理:创建高效可扩展的应用程序
C++程序查找法向量和迹
PHP8底层开发原理实战指南:提升服务器效能
重排数组,使得当 i 为偶数时,arr[i] >= arr[j],当 i 为奇数时,arr[i] <= arr[j],其中 j < i,使用 C++ 语言实现
Golang的垃圾回收:为什么它可以减少开发人员的负担?
C++程序:将一个数组的所有元素复制到另一个数组中
Golang:构建智能系统的基石
为什么AI开发者应该关注Golang?
在C和C++中,逗号(comma)的用法是用来分隔表达式或语句
PHP8底层开发原理解析及新特性应用实例
利用PHP8底层开发原理解析新特性:如何构建出色的Web应用