本篇次要说下PHP8结构器属性晋升的用法,这个个性对于一些须要在结构器中设置或初始化一些类属性的时候十分有用(包含public
、protected
和private
),比方在PHP7中你能够这样定义一个类的属性,而后在构造方法中传值。
class Point { public int $x; private string $y; public function __construct(int $x = 0, string $y='') { $this->x = $x; $this->y = $y; }}
在PHP8中则能够简化为间接在构造函数办法外面定义类的属性
class Point { public function __construct(public int $x = 0, private string $y = '') { // 你能够在结构器中间接输入类的x和y属性的值(也就是传入的x和y变量的值) var_dump($this->x); var_dump($this->y); }}
不过须要留神的是结构器属性只能在结构器办法中定义(如同是废话),而且必须增加public
/protected
/private
,如果不增加的话是不会作为类属性定义的,除非你在父类中曾经定义了结构器属性,比方:
class Test { public function __construct( public int $x = 0 ) {}}class Child extends Test { public function __construct( $x, public int $y = 0, public int $z = 0, ) { parent::__construct($x); }}
在理论应用过程中,还有些细节须要留神。
抽象类或接口的结构器办法不能应用结构器属性定义
abstract class Test { // 谬误 abstract public function __construct(private $x);} interface Test { // 谬误 public function __construct(private $x);}
但Traits中是容许应用的
trait MyTrait{ public function __construct( public string $a, ) {}}
对象类型的结构器属性不能应用null
作为默认值
如果你的结构器属性的类型是一个对象,那么不能够应用null
作为参数默认值
class Test { // 谬误 public function __construct(public Type $prop = null) {}}
但能够应用
class Test { // 正确 public function __construct(public ?Type $prop = null) {}}
不反对callable
类型的结构器属性定义
class Test { // 谬误 public function __construct(public callable $callback) {}}
结构器属性不能应用var
定义
class Test { // 谬误 public function __construct(var $prop) {}}
结构器属性定义也不能应用可变参数
class Test { // Error: Variadic parameter. public function __construct(public string ...$strings) {}}
结构器属性和类属性不能反复定义
比方
class Test { public string $prop; public int $explicitProp; // Error: Redeclaration of property. public function __construct(public string $prop) {}}
但你能够应用结构器属性定义额定的尚未定义过的类属性
class Test { public string $prop; public int $explicitProp; // Correct public function __construct(public int $promotedProp, int $arg) { $this->explicitProp = $arg; }}
只能应用简略默认值
比方,你不能够在参数的默认值中应用函数或者实例化对象。
public function __construct( public string $name = 'Brent', // 谬误 public DateTime $date = new DateTime(),) {}
更多的用法能够自行钻研。