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 中添加了一些新的类和方法:
-
ReflectionGenerator
提供生成器的信息及其状态 -
ReflectionType
报告函数的参数和返回值的类型(为支持新的标量和返回值类型提示) -
ReflectionParameter
有两个新方法确定参数的类型 -
ReflectionFunctionAbstract
有两个新方法来确定返回值的类型
PHP7 中五个鲜有人知的特性