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 中添加了一些新的类和方法:

Leave a Reply

Your email address will not be published. Required fields are marked *

+ 89 = 99