一、函数参数
1、参数后逗号
从 PHP 8.0.0 开始,函数参数列表可以包含一个尾部的逗号,这个逗号将被忽略。这在参数列表较长或包含较长的变量名的情况下特别有用,这样可以方便地垂直列出参数。
function takes_many_args(
$first_arg,
$second_arg,
$a_very_long_argument_name,
$arg_with_default = 5,
$again = 'a default string', // 在 8.0.0 之前,这个尾部的逗号是不允许的。
)
{
// ...
}
2、命名参数
PHP 8.0.0 开始引入了命名参数作为现有位置参数的扩展。命名参数允许根据参数名而不是参数位置向函数传参。这使得参数的含义自成体系,参数与顺序无关,并允许任意跳过默认值。
命名参数通过在参数名前加上冒号来传递。允许使用保留关键字作为参数名。参数名必须是一个标识符,不允许动态指定。
myFunction(paramName: $value);
array_foobar(array: $value);
命名参数也可以与位置参数相结合使用。此种情况下,命名参数必须在位置参数之后。也可以只指定一个函数的部分可选参数,而不考虑它们的顺序
htmlspecialchars($string, double_encode: false);
二、构造器属性提升
PHP 8.0.0 起,构造器的参数也可以相应提升为类的属性。 构造器的参数赋值给类属性的行为很普遍,否则无法操作。 而构造器提升的功能则为这种场景提供了便利。
//php8之前代码
class Point {
protected int $x;
protected int $y;
public function __construct(int $x, int $y = 0) {
$this->x = $x;
$this->y = $y;
}
}
//php8代码
class Point {
public function __construct(protected int $x, protected int $y = 0) {
}
}
当构造器参数带访问控制(visibility modifier)时,PHP 会同时把它当作对象属性和构造器参数, 并赋值到属性。 构造器可以是空的,或者包含其他语句。 参数值赋值到相应属性后执行正文中额外的代码语句。
并非所有参数都需要提升。可以混合提升或不提升参数作为属性,也不需要按顺序。 提升后的参数不影响构造器内代码调用。
注意:
对象属性的类型不能为?callable?以避免为引擎带来混淆。 因此提升的参数也不能是?callable。 其他任意?类型声明?是允许的。
注意:
放在构造器提升参数里的属性会同时复制为属性和参数。
三、match表达式?
$return_value = match (subject_expression) {
single_conditional_expression => return_expression,
conditional_expression1, conditional_expression2 => return_expression,
};
The?match ?expression branches evaluation based on an identity check of a value. Similarly to a?switch ?statement, a?match ?expression has a subject expression that is compared against multiple alternatives. Unlike?switch , it will evaluate to a value much like ternary expressions. Unlike?switch , the comparison is an identity check (=== ) rather than a weak equality check (== ). Match expressions are available as of PHP 8.0.0.
The?match ?expression is similar to a?switch ?statement but has some key differences:
- A?
match ?arm compares values strictly (=== ) instead of loosely as the switch statement does. - A?
match ?expression returns a value. match ?arms do not fall-through to later cases the way?switch ?statements do.- A?
match ?expression must be exhaustive.
?四、Nullsafe 方法和属性
自 PHP 8.0.0 起,类属性和方法可以通过 "nullsafe" 操作符访问:??-> 。 除了一处不同,nullsafe 操作符和以上原来的属性、方法访问是一致的: 对象引用解析(dereference)为?null ?时不抛出异常,而是返回?null 。 并且如果是链式调用中的一部分,剩余链条会直接跳过。
此操作的结果,类似于在每次访问前使用?is_null()?函数判断方法和属性是否存在,但更加简洁。
// 自 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;
}
}
?五、其他新特性
简介
A?WeakMap?is map (or dictionary) that accepts objects as keys. However, unlike the otherwise similar?SplObjectStorage, an object in a key of?WeakMap?does not contribute toward the object's reference count. That is, if at any point the only remaining reference to an object is the key of a?WeakMap, the object will be garbage collected and removed from the?WeakMap. Its primary use case is for building caches of data derived from an object that do not need to live longer than the object.
WeakMap?implements?ArrayAccess,?Iterator, and?Countable, so in most cases it can be used in the same fashion as an associative array.
类摘要
final class WeakMap implements Countable, ArrayAccess, IteratorAggregate {
/* 方法 */
public __construct()
public count(): int
abstract public getIterator(): Traversable
public offsetExists(object $object): bool
public offsetGet(object $object): mixed
public offsetSet(object $object, mixed $value): void
public offsetUnset(object $object): void
}
$wm = new WeakMap();
$o = new StdClass;
class A {
public function __destruct() {
echo "Dead!\n";
}
}
$wm[$o] = new A;
var_dump(count($wm));
echo "Unsetting...\n";
unset($o);
echo "Done\n";
var_dump(count($wm));
//输出
//int(1)
//Unsetting...
//Dead!
//Done
//int(0)
2、新增?ValueError?类
|