在我们全新升级的课程《Laravel 9优雅实战入门(第三版)》里,我们在重构controller数据逻辑到Repository中时,使用了PHP 8的构造函数简化传参功能,这里我们就对此扩展一下,帮助学员更好理解和应用:
class Point {
public int $x;
public function __construct( int $x = 0 ) {
$this->x = $x;
}
}
传统上,我们要想往构造函数里传参,并且将其赋值给这个对象或类,供后期使用,我们都得上面这么写。写多了,就感觉挺烦的,尤其是变量多的时候:
class Point {
public int $x;
public int $y;
public int $z;
public function __construct(
int $x = 0,
int $y = 0,
int $z = 0,
) {
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
}
比如这种情况,每个变量名就得写四遍,所以在PHP 8.0开始,可以进一步简写如下:
class Point {
public function __construct(
public int $x = 0,
public int $y = 0,
public int $z = 0,
) {}
}
不能用于抽象的构造函数中
这种新写法,在非抽象的类或trait里,是可以的,也即可实例化的类里。但是在抽象的类或interface里,就不允许了,比如下面写法是不行的:
abstract class Test {
// Error: Abstract constructor.
abstract public function __construct(private $x);
}
interface Test {
// Error: Abstract constructor.
public function __construct(private $x);
}
注意这个Abstract constructor的报错信息,将来遇到的时候知道是怎么回事。
默认为空值时
class Test {
// Error: Using null default on non-nullable property
public function __construct(public Type $prop = null) {
}
}
比如,如果这么写,它会报错Error: Using null default on non-nullable property,抱怨你将不可为空的属性,设置为空的默认值。也即你既然说了$prop是特定的Type,那么它就不能是null,类型就对不上。
但是如果我们明确地声明,这个特定Type,可以为空,是可以的,比如下面这样:
class Test {
// Correct: Make the type explicitly nullable instead
public function __construct(public ?Type $prop = null) {}
}
所以这里也是,当显示报错说Error: Using null default on non-nullable property的时候,也要知道是怎么回事。
Callable Type不被允许
由于callable不是一个被允许的属性类型,所以下面这么写会报错:
class Test {
// Error: Callable type not supported for properties.
public function __construct(public callable $callback) {}
}