本文摘自 php.net
1. 新增命名参数的功能
通过参数列表可以传递信息到函数,即以逗号作为分隔符的表达式列表。函数在实际调用之前,值参数是从左向右求值的(及早求值)。
1.1 命名参数的语法
<?php
myFunction(paramName: $value);
array_foobar(array: $value);
// 不支持。
function_name($variableStoringParamName: $value);
1.2 通过位置传参与命名参数的对比
<?php
// 使用顺序传递参数:
array_fill(0, 100, 50);
// 使用命名参数:
array_fill(start_index: 0, count: 100, value: 50);
2. 新增注解的功能
3. 构造器属性提升
PHP 8.0.0 起,构造器的参数也可以相应提升为类的属性。 构造器的参数赋值给类属性的行为很普遍,否则无法操作。 而构造器提升的功能则为这种场景提供了便利。 因此上面的例子可以用以下方式重写:
<?php
class Point {
public function __construct(protected int $x, protected int $y = 0) {
}
}
当构造器参数带访问控制(visibility modifier)时,PHP 会同时把它当作对象属性和构造器参数, 并赋值到属性。 构造器可以是空的,或者包含其他语句。 参数值赋值到相应属性后执行正文中额外的代码语句。
并非所有参数都需要提升。可以混合提升或不提升参数作为属性,也不需要按顺序。 提升后的参数不影响构造器内代码调用。
4. 新增 match
表达式
match
表达式基于值的一致性进行分支计算。match
表达式和switch
语句类似, 都有一个表达式主体,可以和多个可选项进行比较。 与switch
不同点是,它会像三元表达式一样求值。 与switch
另一个不同点,它的比较是严格比较(===
)而不是松散比较(==
)。 Match 表达式从 PHP 8.0.0 起可用。
<?php
$food = 'cake';
$return_value = match ($food) {
'apple' => 'This food is an apple',
'bar' => 'This food is a bar',
'cake' => 'This food is a cake',
default => 'This is default'
};
var_dump($return_value);
以上例程会输出
string(19) "This food is a cake"
4.1 注意
‼️ 不一定要使用
match
表达式的结果。‼️
match
表达式必须使用分号;
结尾。
4.2 match 与 switch 的区别
match
表达式跟switch
语句相似,但是有以下关键区别:
match
比较分支值,使用了严格比较 (===
), 而 switch 语句使用了松散比较。match
表达式会返回一个值。match
的分支不会像switch
语句一样, 落空时执行下个 case。match
表达式必须彻底列举所有情况。
4.3 逗号分隔(逻辑 OR)
<?php
$result = match ($x) {
// 匹配分支:
$a, $b, $c => 5,
// 等同于以下三个分支:
$a => 5,
$b => 5,
$c => 5,
};
4.4 使用 match 表达式处理非一致性检查
可以使用
match
表达式将true
作为主项表达式来处理非一致性条件的情况。
示例: 针对整数范围, 使用宽泛的表达式匹配分支
<?php
$age = 23;
$result = match (true) {
$age >= 65 => 'senior',
$age >= 25 => 'adult',
$age >= 18 => 'young adult',
default => 'kid',
};
var_dump($result);
以上例程会输出
string(11) "young adult"
示例: 针对字符串内容,使用宽泛的表达式匹配分支
<?php
$text = 'Bienvenue chez nous';
$result = match (true) {
str_contains($text, 'Welcome') || str_contains($text, 'Hello') => 'en',
str_contains($text, 'Bienvenue') || str_contains($text, 'Bonjour') => 'fr',
// ...
};
var_dump($result);
以上例程会输出
string(2) "fr"
5. 新增Nullsafe 运算符(?->
)
自 PHP 8.0.0 起,类属性和方法可以通过 “nullsafe” 操作符访问:
?->
。 除了一处不同,nullsafe 操作符和以上原来的属性、方法访问是一致的: 对象引用解析(dereference)为null
时不抛出异常,而是返回null
。 并且如果是链式调用中的一部分,剩余链条会直接跳过。此操作的结果,类似于在每次访问前使用 is_null() 函数判断方法和属性是否存在,但更加简洁。
<?php
// 自 PHP 8.0.0 起可用
$result = $repository?->getUser(5)?->name;
// 上边那行代码等价于以下代码
if (is_null($repository)) {
$result = null;
} else {
$user = $repository->getUser(5);
if (is_null($user)) {
$result = null;
} else {
$result = $user->name;
}
}