本文目录导读:

在 PHP 中,构造函数(__construct)的“提升”通常指的是 PHP 8 引入的构造函数属性提升(Constructor Property Promotion),这是一种语法糖,让你在构造函数参数中直接声明和初始化类属性,从而减少重复代码。
什么是构造函数属性提升?
在 PHP 8 之前,声明一个类的属性需要三步:
class User {
private string $name;
private int $age;
public function __construct(string $name, int $age) {
$this->name = $name;
$this->age = $age;
}
}
PHP 8 的构造函数属性提升允许你将属性声明和赋值合并到构造函数的参数列表中:
class User {
public function __construct(
private string $name,
private int $age
) {}
}
具体语法规则
基本用法
在构造函数参数前加上访问修饰符(public、protected、private)或 readonly:
class Product {
public function __construct(
public readonly string $sku, // 公共只读属性
private float $price, // 私有属性
protected int $quantity = 0 // 默认值
) {}
}
等同于:
class Product {
public readonly string $sku;
private float $price;
protected int $quantity = 0;
public function __construct(string $sku, float $price, int $quantity = 0) {
$this->sku = $sku;
$this->price = $price;
$this->quantity = $quantity;
}
}
混合使用
你可以在同一个构造函数中混合使用提升属性和普通参数:
class Order {
private array $items = [];
public function __construct(
private int $id,
private string $status,
array $initialItems = [] // 普通参数,不会提升为属性
) {
$this->items = $initialItems;
}
}
使用 readonly 属性
PHP 8.1 之后,readonly 可以用于提升属性:
class Config {
public function __construct(
readonly private string $host,
readonly private int $port = 3306
) {}
}
优点
| 特点 | 说明 |
|---|---|
| 减少样板代码 | 避免重复写属性声明和 $this-> 赋值 |
| 提高可读性 | 构造函数的参数列表直接展示了类的核心属性 |
| 减少错误 | 不会漏掉赋值或拼写错误 |
| 与类型声明结合 | 原生支持类型、默认值和参数命名 |
注意事项
只能用于简单的属性赋值
如果属性需要额外的逻辑处理(如验证、转换),必须使用传统方式:
class User {
private string $email;
public function __construct(string $email) {
// 需要验证逻辑,不能提升
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException("Invalid email");
}
$this->email = $email;
}
}
不能与构造函数体中的 $this-> 冲突
一旦某个参数被提升为属性,构造函数体内就不能再次设置同名属性(除非你主动在体里再次赋值,但会覆盖提升的值)。
不能用于 static 或 var 修饰符
构造函数属性提升只支持 public、protected、private 和 readonly。
不能与 __construct 的引用参数一起使用
// ❌ 错误:提升属性不支持引用
public function __construct(private string &$name) {}
实际应用示例
数据传输对象(DTO)
class CreateUserRequest {
public function __construct(
public readonly string $name,
public readonly string $email,
public readonly ?string $phone = null
) {}
}
// 使用
$request = new CreateUserRequest(name: 'Alice', email: 'alice@example.com');
配置类
class DatabaseConfig {
public function __construct(
public readonly string $driver = 'mysql',
public readonly string $host = 'localhost',
public readonly int $port = 3306,
public readonly string $username = 'root',
#[\SensitiveParameter] public readonly string $password = ''
) {}
}
值对象(Value Object)
class Money {
public function __construct(
public readonly float $amount,
public readonly string $currency
) {
if ($amount <= 0) {
throw new InvalidArgumentException('Amount must be positive');
}
}
}
与其他特性结合
匹配枚举
enum Status: string {
case PENDING = 'pending';
case ACTIVE = 'active';
}
class Entity {
public function __construct(
public readonly int $id,
public readonly Status $status = Status::PENDING
) {}
}
联合类型和可空类型
class Response {
public function __construct(
public readonly int $code,
public readonly string|array|null $data = null
) {}
}
- 构造函数属性提升是 PHP 8 的语法糖,用于简化常见的属性声明+赋值模式。
- 适用于无需额外处理逻辑的属性。
- 支持
public、protected、private、readonly。 - 显著减少样板代码,提高可读性和维护性。
- 对于复杂逻辑的场景,仍然使用传统写法。
这是现代 PHP 开发中非常推荐使用的特性,尤其是在 DTO、配置类、简单实体对象中。