PHP7 中五个鲜有人知的特性

本文是 Five Lesser-Known Features of PHP 7 的译文 PHP 7 即将发布(原文如此,现在 PHP 7 已经正式发布),我觉得检查 PHP 7 带来的一些鲜为人知的新特性是一件非常酷的事情:

1. define()可以定义数组常量

自 PHP 5.6 开始,可以使用 const 关键字在类中定义常量数组:

const LUCKY_NUMBERS = [4, 8, 15, 16, 23, 42];

PHP 7 将同样的功能引入到 define() 函数中:

define(‘LUCKY_NUMBERS’, [4, 8, 15, 16, 23, 42]);

2. 被0除

PHP 7 之前,被0除会导致一条 E_WARNING 并返回 false。一个数字运算返回一个布尔值是没有意义的,所以 PHP 7 会返回如下的 float 值之一(同时出发一条 E_WARNING):

  • +INF
  • -INF
  • NAN

比如:

var_dump(42/0); // float(INF) + E_WARNING
var_dump(-42/0); // float(-INF) + E_WARNING
var_dump(0/0); // float(NAN) + E_WARNING

当使用取模运算符(%)的时候,PHP 7 会抛出一个 DivisionByZeroError 异常:

var_dump(0%0); // DivisionByZeroError

另外,在新的 intdiv() 函数中,如果你提供了有效的int值,但最终会导致int值溢出,则该函数会抛出 ArithmeticError 异常:

var_dump(intdiv(PHP_INT_MIN, -1)); // ArithmeticError

3. 带过滤的 unserialize()

反序列化不受信任的数据是非常危险的习惯,因为恶意用户可能会注入他们自己的数据和对象到应用程序中。对于对象的析构函数来说,这尤其危险,因为这些方法一定会被执行,即使你实际不使用使用反序列化后的对象这篇文章很好地论证了这个潜在的漏洞。

PHP 7 因此给 unserialize() 函数添加了一个 array $options 参数来控制反序列化过程。它仅仅支持 allowed_classes 选项来控制是否对象的反序列化。改选项可以取如下值:

  • true 允许所有的对象被还原(默认值)
  • false 不允许所有的对象被还原
  • string[] 提供一个允许的类名列表

如果一个类不被允许,PHP 将会将其反序列化为一个 “incomplete class” 对象 (__PHP_Incomplete_Class)。PHP 在反序列化一个不存在的类的时候也是同样的表现。 一些使用这个特性的例子:

// 如下代码将会反序列化所有内容,和之前的PHP一样
$data = unserialize($foo);
$data = unserialize($foo, [‘allowed_classes’ => true]);

// 如下代码会将所有的对象转化为 __PHP_Incomplete_Class 对象
$data = unserialize($foo, [‘allowed_classes’ => false]);

// 如下代码会将除 Foo 和 Bar 以外的所有对象都转换为 __PHP_Incomplete_Class 对象
$data = unserialize($foo, [‘allowed_classes’ => [‘Foo’, ‘Bar’]]);

4. IntlChar

PHP 通过 intl 扩展来支持国际化 (i18n) 和本地化 (l10n) 。此扩展仅仅是对 ICU 库的基础包装,并提供了和 ICU 库类似的方法和特性。 PHP 7 通过新的 IntlChar 类暴露出 ICU 中的 Unicode 字符特性。这个类包含了600个常量和59个静态方法,所以我们不会再次详述,但是如下是一些你可以觉得有用的例子:

// 返回包含该字符的 Unicode 分配块(Unicode allocation block)
public static function getBlockCode(mixed $codepoint): int;

// 当前的代码点(code point)是否是字母
static public function isalpha(mixed $codepoint): bool;

// 当前的代码点(code point)是否是标点字符
static public function ispunct(mixed $codepoint): bool;

// 当前的代码点(code point)是否是“图像”字符
// (可打印字符, 不包括空格).
static public function isgraph(mixed $codepoint): bool;

// 当前的代码点(code point)是否是空格或者横向空格
static public function isblank(mixed $codepoint): bool;

// 返回字符的小写形式,如果该字符没有小写形式,则返回自身
static public function tolower(mixed $codepoint): mixed;

// 返回该字符的 Unicode 字符名
static public function charName(mixed $codepoint, int $nameChoice = IntlChar::UNICODE_CHAR_NAME)

你可以在这里找到全部的方法列表:PHP::IntlChar

5. 反射增强

PHP 7 也向反射 API 中添加了一些新的类和方法:

作者

Robert Lu

发布于

2015-12-27

许可协议

评论