PHP 7.1 release版本发布在即,本文整理一下 7.1 中的一些新特性以供了解。所有内容均选自官方 RFC 文档。
可空类型
可空类型主要用于参数类型声明和函数返回值声明。主要的两种形式如下:
<?phpfunction answer(): ?int{return null; //ok}function answer(): ?int{return 42; // ok}function say(?string $msg) {if ($msg) {echo $msg;}}从例子很容易理解,所指的就是通过
? 的形式表明函数参数或者返回值的类型要么为指定类型,要么为
null。此方法也可用于接口函数的定义:
<?phpinterface Fooable {function foo(?Fooable $f);}但有一个需要注意的地方:如果函数本身定义了参数类型并且没有默认值,即使是可空的,也不能省略,否则会触发错误。如下:
<?phpfunction 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个字符还是很实在的)。
<?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 来实现:
<?phplist($a, $b, $c) = $array;是否也可以通过
[] 的简写来实现呢?
<?php[$a, $b, $c] = $array;以及下一个特性中会提到的 list 指定 key:
<?php["a" => $a, "b" => $b, "c" => $c] = $array;PHP7.1 实现了这个特性。但是要注意的是:出现在左值中的
[] 并不是数组的简写,是
list() 的简写。但是并不仅仅如此,新的
list() 的实现并不仅仅可以出现在左值中,也能在
foreach 循环中使用:
<?phpforeach ($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
上文提到过,新的
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 的数字形式并且不能调整顺序。执行以下语句:
<?phplist($a, $b) = [1 => "1", 2 => "2"];会得到
PHP error: Undefined offset: 0... 的错误。而新的实现则可以通过以下方式来调整赋值:
<?phplist(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;}void 返回类型
PHP7.0 添加了指定函数返回类型的特性,但是返回类型却不能指定为
void,7.1 的这个特性算是一个补充:
<?phpfunction should_return_nothing(): void {return 1; // Fatal error: A void function must not return a value}以下两种情况都可以通过验证:
<?phpfunction lacks_return(): void {// valid}function returns_nothing(): void {return; // valid}定义返回类型为
void 的函数不能有返回值,即使返回
null 也不行:
<?phpfunction 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 也只适用于返回类型,并不能用于参数类型声明,或者会触发错误:
<?phpfunction foobar(void $foo) { // Fatal error: void cannot be used as a parameter type}类函数中对于返回类型的声明也不能被子类覆盖,否则会触发错误:
<?phpclass 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}}类常量属性设定
这个特性说起来比较简单,就是现在类中的常量支持使用
public、
private 和
protected 修饰了:
<?phpclass Token {// 常量默认为 publicconst 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 属性:
<?phpinterface ICache {public const PUBLIC = 0;const IMPLICIT_PUBLIC = 1;}为了应对变化,反射类的实现也相应的丰富了一下,增加了
getReflectionConstant 和
getReflectionConstants 两个方法用于获取常量的额外属性:
<?phpclass testClass{const TEST_CONST = "test";}$obj = new ReflectionClass( "testClass" );$const = $obj->getReflectionConstant( "TEST_CONST" );$consts = $obj->getReflectionConstants();多条件 catch
在以往的
try ... catch 语句中,每个
catch 只能设定一个条件判断:
<?phptry {// Some code...} catch (ExceptionType1 $e) {// 处理 ExceptionType1} catch (ExceptionType2 $e) {// 处理 ExceptionType2} catch (Exception $e) {// ...}新的实现中可以在一个
catch 中设置多个条件,相当于或的形式判断:
<?phptry {// 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
PHP 7革新与性能优化 http://www.linuxidc.com/Linux/2015-09/123136.htmPHP 7 ,你值得拥有 http://www.linuxidc.com/Linux/2015-06/118847.htm 在 CentOS 7.x / Fedora 21 上面体验 PHP 7.0 http://www.linuxidc.com/Linux/2015-05/117960.htm CentOS 6.3 安装LNMP (PHP 5.4,MyySQL5.6) http://www.linuxidc.com/Linux/2013-04/82069.htm 在部署LNMP的时候遇到Nginx启动失败的2个问题 http://www.linuxidc.com/Linux/2013-03/81120.htm Ubuntu安装Nginx php5-fpm MySQL(LNMP环境搭建) http://www.linuxidc.com/Linux/2012-10/72458.htm 《细说PHP》高清扫描PDF+光盘源码+全套教学视频 http://www.linuxidc.com/Linux/2014-03/97536.htm CentOS 6中配置PHP的LNMP的开发环境 http://www.linuxidc.com/Linux/2013-12/93869.htm
PHP 的详细介绍:请点这里
PHP 的下载地址:请点这里
本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-09/135297.htm