# PHP 7.2 新功能
> PHP 7.2 已經在 2017 年 11 月 30 日 正式發布 。這次發布包含新特性、功能,及優化,以讓我們寫出更好的代碼。在這篇文章裡,我將會介紹一些 PHP 7.2 最有趣的語言特性。
[TOC]
## **核心改进**
#### 参数类型声明
我们可以制定函数参数的预期声明类型。如果传参类型错误,PHP就回抛出一个错误。
```php
class MyClass {
public $var = 'Hello World';
}
$myclass = new MyClass;
function test(MyClass $myclass){
return $myclass->var;
}
echo test($myclass);
```
这段代码中,传入不正确的参数数据类型会导致一个致命错误。
从 PHP 7.2 类型提示 可以被用在对象型数据上,并且这个改进允许**通用对象类型**作为一个函数或者方法的参数。这里有个例子:
```php
class MyClass {
public $var = '';
}
class FirstChild extends MyClass {
public $var = 'My name is Jim';
}
class SecondChild extends MyClass {
public $var = 'My name is John';
}
$firstchild = new FirstChild;
$secondchild = new SecondChild;
function test(object $arg) {
return $arg->var;
}
echo test($firstchild);
echo test($secondchild);
```
------------------------
#### 对象返回类型声明
若变量类型指定函数参数的预期类型,返回值类型同样也可以被指定预期类型。
```
返回类型声明 指定一个函数应该返回的预期类型
```
```php
class MyClass {
public $var = 'Hello World';
}
$myclass = new MyClass;
function test(MyClass $arg) : object {
return $arg;
}
echo test($myclass)->var;
```
-------
#### 参数类型泛化
PHP 目前是不允许子类和它父类或者接口的参数类型有任何差异的。
参考以下代码:
```php
class MyClass {
public function myFunction(array $myarray) { /* ... */ }
}
class MyChildClass extends MyClass {
public function myFunction($myarray) { /* ... */ }
}
```
子类中的参数类型在实现多态时,发生了与父类差异,省略了参数类型。
在 PHP 7.0 中,会产生以下警告:
```
Warning: Declaration of MyChildClass::myFunction($myarray) should be compatible with MyClass::myFunction(array $myarray) in %s on line
```
从 PHP 7.2 起,我们可以忽略子类中的类型 而不会破坏任何代码。这个方案使得我们可以在库中升级类,从而可以使用类型提示,却无需更新其所有的子类。
这里是7.0和7.2之间的差异,相比7.0,7.2更友好。
----------
#### 列表语法中的尾随逗号
`列表语法说的也就是 数组 最后一个元素尾随一个逗号的情景`
在 PHP 数组的最后一个元素上使用尾随逗号是 合法语法 ,并且 有时候鼓励这么做 ,可以很轻松的避免增加新元素的时候出现缺失逗号的错误。 从 PHP 7.2 在 分组命名空间 中,我们可以使用尾随逗号 。
## **安全性改进**
#### 密码哈希中的Argon2
Argon2 是荣获 2015 年密码哈希算法比赛中的冠军的强大哈希算法, PHP 7.2 将其作为安全 Bcrypt 算法的替代品。
新版的 PHP 中引入了 PASSWORD_ARGON2I 常量,现在可以在 password_* 系列函数中使用:
```php
password_hash('password',PASSWORD_ARGON2I);
```
#### 弃用
PHP 5.1 中 `__autoload` 函数已被 spl_autoload_register 取代。现在会在编译期间报一个弃用通知。
当抛出致命错误的时候,会创建 `$php_errormsg` 局部变量。 PHP 7.2 中应该使用 error_get_last 和 error_clear_last 替代这种做法。
`create_function()` 可以创建一个具有函数名称的函数,将函数参数和函数体作为该函数的列表传入。因为安全问题和性能表现不佳,它被标记为弃用,鼓励用封装替代。
`mbstring.func_overload` ini 设置为非零值已经被标记为弃用。
`(unset) cast` 是个总是返回 null 的表达式,并且毫无用处。
如果传入第二个参数,parse_str() 将查询字符串解析到数组当中, 否则解析到本地符号表。 因为安全原因, 不建议 在函数作用域中动态设置变量,使用不带第二个参数的 parse_str() 将抛一个弃用通知。
`gmp_random()` 是平台相关的,将会被废弃。使用 gmp_random_bits() 和 gmp_random_rage() 代替。
`each()` 在数组上迭代的行为非常像 foreach(),但 foreach() 基于一些原因而成为更优选择,例如它的速度快上 10 倍。现在在循环中使用前者将会抛出一个废弃提示。
`assert()` 函数检查给定的断言,并在结果为 FALSE 的时候进行相关处理。 带有字符串参数的 `assert()` 现在已经弃用,因为它有 RCE 漏洞。 zend.assertion ini 选项可以关闭断言表达式。
`$errcontext` 是一个包含产生错误时的局部变量数组。它可被作为错误处理程序 set_error_handler() 函数的最后一个参数。