2020年php8最新功能介绍 php 8( 三 )


数组索引支持负数在PHP中,如果数组以负索引(start_index < 0)开头,则以下索引自动从0开始 。看下面的例子:
$a = array_fill(-5, 4, true);
var_dump($a);
在PHP 7.4中,结果如下:
array(4) {
[-5]=>
bool(true)
[0]=>
bool(true)
[1]=>
bool(true)
[2]=>
bool(true)
}
在PHP 8中,上面的代码将结果如下:
array(4) {
[-5]=>
bool(true)
[-4]=>
bool(true)
[-3]=>
bool(true)
[-2]=>
bool(true)
}
联合类型2.0联合类型接受可以是不同类型的值 。目前,PHP不支持联合类型,但?Type语法和特殊iterable类型除外 。
在PHP 8之前,联合类型只能在phpdoc批注中指定:
class Number {
/**
* @var int|float $number
*/
private $number;
/**
* @param int|float $number
*/
public function setNumber($number) {
$this->number = $number;
}
/**
* @return int|float
*/
public function getNumber() {
return $this->number;
}
}
根据联合类型2.0 RFC提议在函数签名中添加对联合类型的支持,这样我们就不再依赖内联文档,而是使用T1|T2|…语法来定义联合类型:
class Number {
private int|float $number;
public function setNumber(int|float $number): void {
$this->number = $number;
}
public function getNumber(): int|float {
return $this->number;
}
}
联合类型支持所有可用类型,但有一些限制:
void类型不能是并集的一部分,因为void意味着函数不返回任何值 。
null类型仅支持union的类型,但它的使用作为一个独立的类型是不允许的 。
(?T)也可以使用可为null的类型表示法,表示T|null,但不允许在联合类型中包含该表示法(不允许使用?T1|T2,应该用T1|T2|null改用) 。
尽可能多的功能(即strpos(),strstr(),substr()等等)包括false可能的返回类型中,false伪类型也支持 。
内部函数的一致类型错误传递非法类型的参数时,内部函数和用户定义函数的行为会有所不同 。
用户定义的函数会引发TypeError,但是内部函数会根据多种情况以多种方式运行 。无论如何,典型的行为是发出警告并返回null 。比如下面的代码在PHP 7.4会导致告警
var_dump(strlen(new stdClass));
Warning: strlen() expects parameter 1 to be string, object given in /path/to/your/test.php on line 4
NULL
如果启用strict_types,或参数信息指定类型,则行为将有所不同 。在这种情况下,将检测到类型错误并导致TypeError 。
为了消除这些不一致之处,RFC建议使内部参数解析API在参数类型不匹配的情况下抛出ThrowError 。
在PHP 8中,上面的代码将抛出致命错误:
Fatal error: Uncaught TypeError: strlen(): Argument #1 ($str) must be of type string, object given in /path/to/your/test.php:4
Stack trace:
#0 {main}
thrown in /path/to/your/test.php on line 4
抛出表表达式
在PHP中,throw是一个语句,因此无法在只允许使用表达式的地方使用它 。
建议将throw语句转换为表达式,这样就可以在允许表达式的任何上下文中使用它 。例如,箭头符号,空合并运算符,三元判断和合并运算符等:
$callable = fn() => throw new Exception();
// $value is non-nullable.
$value = https://www.shianvip.com/article/$nullableValue ?? throw new InvalidArgumentException();
// $value is truthy.
$value = https://www.shianvip.com/article/$falsableValue ?: throw new InvalidArgumentException();
WeakMapWeakMap是弱引用键的数据(对象)的集合,这意味着不会阻止对它们的垃圾回收 。

经验总结扩展阅读