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 {// 常量默认为 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 属性:

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

PHP 7.1 新特性一览相关推荐

  1. 深入解析 | Oracle Database 20c 十大新特性一览

    在2020年2月14日,Oracle 正式宣布在 Oracle Cloud 发布 Database 20c 的预览版,同时发布了所有的官方文档. 为了和大家及时分享关于 Oracle 20c 引人瞩目 ...

  2. Java8-19新特性一览 ,认识全新的前沿技术

    文章目录 Java8-19新特性一览 ,认识全新的前沿技术 前言 你的收获 Java发展趋势 准备工作 新特性 1.接口private 1).说明 2).案例 3).注意 2.类型推断 1).说明 2 ...

  3. 【机器学习】scikit-learn 1.0 版本重要新特性一览

    1 简介 就在几天前,著名的机器学习框架scikit-learn在pypi上释放了其1.0rc1版本,这里给大家科普一下,版本号中的rc是Release Candidate的简称,代表当前的版本是一个 ...

  4. Oracle Database 20c 十大新特性一览

    从大会的分享和公布的资料中,我们整理了其中重要的新特性,汇聚成10个方向,按照惯例,和大家分享. 历史回顾: Oracle Database 20c 新特性: 1.原生的区块链支持 - Native ...

  5. JDK 13 新特性一览

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:木九天 my.oschina.net/mdxlcj/blog ...

  6. Spring Framework 5.2 正式发布,14项新特性一览

    点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 作者 | xplanet 来源 | http://oschina.net/news/1103 ...

  7. Java 11将于本月25日发布,新特性一览

    作者:漫画编程 来源:漫画编程 2017年8月,JCP执行委员会提出将Java的发布频率改为每六个月一次.该决定将在Java 9正式发布之后开始实行. 2018年3月,Java 10如期而至.目前已经 ...

  8. oracle 峰度 函数,Oracle Database 21c 十大新特性一览

    摘要:Oracle 考虑到 2020 年我们的客户将面临前所未有的经济和业务中断.我们决定不将 Database 20c Preview 版本升级为 General Availability. 相反, ...

  9. Apache Spark 1.5发布,新特性一览

    Apache Spark是一个围绕速度.易用性和复杂分析构建的大数据处理框架.最初在2009年由加州大学伯克利分校的AMPLab开发,并于2010年成为Apache的开源项目之一.Apache Spa ...

  10. [转]ES6、ES7、ES8、ES9、ES10新特性一览 (个人整理,学习笔记)

    目录 1.ES6新特性(2015) 1.1模块化(Module) 1.1.1导出(export) 1.1.2导入(import) 1.2箭头(Arrow)函数 1.2.1箭头函数的结构 1.3默认参数 ...

最新文章

  1. 《裂变》作者爆料:欺世盗名者绝非唐骏一人
  2. 注意区分Mb(Mbps)与MB(million bit和million Byte)
  3. Python3 数字(Number)
  4. shiro学习(14):springMVC结合shiro完成认证
  5. Ubuntu搭建联盟链,实现节点之间数据同步
  6. mysql语句修改zencart产品原价为特价的倍数
  7. 如何设置mysql远程访问
  8. nginx1.8.1反向代理、负载均衡功能的实现
  9. php之获取ip(网站地址)
  10. SAI红绿蓝三原色叠加效果
  11. EXCEL函数常用技巧浅析
  12. 矩阵连乘问题算法思想_动态规划之矩阵连乘问题
  13. python 广告联盟_谷歌广告月入10000美金的一些经验谈
  14. Raspberry-Pi-PICO系列--第七篇 创建自己的工程
  15. 数据库 “投毒”修复方案
  16. 2018 中国人口研究,净增长500多万人。5年后注定人口负增长
  17. 计算机组成原理笔记(8)---机器指令、寻址方式
  18. k8s 服务注册与发现(二)Kubernetes内部域名解析原理
  19. SPSS 探索性因素分析(图文+数据集)【SPSS 033期】
  20. LINUX提权入门手册

热门文章

  1. 【Android Developers Training】 7. 添加Action Buttons
  2. 博弈-Green Hackenbush(无向图删边)
  3. 设计模式之抽象状态模式
  4. Asp.net MVC权限设计思考 (二)逻辑部分实现
  5. SendMessage,PostMessage
  6. Java--继承(三)
  7. Windows下C语言的Socket编程例子(TCP和UDP)
  8. JAVA程序设计(11)-----面对对象0基础设计 麻将 创建麻将牌 然后洗牌 发牌~ 恩 就这样...
  9. bzoj1088: [SCOI2005]扫雷Mine
  10. svn: No repository found in 'svn:..解决方案