经历了近半年的alpha版本测试后,PHP在2020年11月26号正式发布了8.0版本:https://www.php.net/releases/8.0/en.php
今天我们就来浏览一下PHP 8.0中出现的主要特性,以及它给我们安全研究人员带来的挑战。
命名参数 Named Arguments
PHP 8 以前,如果我们需要给一个函数的第N个参数传参,那么这个参数前面的所有参数,我们都需要传参。但是实际上有些参数是具有默认值的,这样做显得多此一举。
比如,我们要给htmlspecialchars的第4个参数传递false,在PHP 8 以前需要传入4个参数:
htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
在8.0以后增加了命名参数,我们只需要传递必需的参数和命名参数即可,方便了很多:
htmlspecialchars($string, double_encode: false);
属性注释 Attributes
属性注释是我自己取得名字,在英文原文中是单词「Attributes」(在C++、C#、Rust里也是相同的单词,但翻译有些差别)。这个新语法有点类似Python里的修饰器,以及Java里的Annotation。
但是,PHP里Attributes的作用还是更偏向于替换以前的doc-block,用于给一个类或函数增加元信息,而不是类似Python的修饰器那样,可以动态地劫持函数的输入与输出。
属性注释的简单例子:
#[ListensTo('error')]
function onerror() {// do something
}
上面这个例子实际测试你会发现,属性注释里的东西也真的只是一个注释,执行上述的代码也不会去调用ListensTo类。这也印证了上面所说的,Attributes只是对以前doc-block的一个接纳,而非创造了一种HOOK函数的方式。
如果你需要执行Attributes里面的代码,仍然需要通过反射来做到,比如:
#[Attribute]
class ListensTo {public string $event;function __construct($event) {$this->event = $event;}
}#[ListensTo('error')]
function onerror()
{// do something
}$listeners = [];
$f = new ReflectionFunction('onerror');
foreach($f->getAttribute