在我们全新升级的课程《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) {}
}
最后修改:2023 年 03 月 07 日
如果觉得我的文章对你有用,请随意赞赏