只读属性(PHP 8.1)
本课属于 Coddy PHP 学习旅程的“面向对象编程”单元。第 19 课,共 91 课。
PHP 8.1 引入了 readonly 属性,这些属性只能赋值一次,之后不能修改。与常量不同,readonly 属性是在对象初始化时设置的,而不是在类定义时设置的。
你可以在类型声明前添加 readonly 关键字来声明只读属性:
<?php
class User {
public readonly string $id;
public readonly string $name;
public function __construct(string $id, string $name) {
$this->id = $id;
$this->name = $name;
}
}
$user = new User("U001", "Alice");
echo $user->id . "\n";
echo $user->name;
输出:
U001
Alice赋值后,尝试更改只读属性会导致错误。这类属性非常适合存储在对象的整个生命周期内都应保持不变的值,例如 ID 或创建时间戳。
只读属性必须声明类型,并且只能在声明它的类内部赋值一次(通常在构造函数中)。与普通属性不同,它们不能在声明时设置默认值。它们可以使用任何可见性修饰符:
<?php
class Product {
public function __construct(
public readonly string $sku,
private readonly float $cost
) {}
public function getCost(): float {
return $this->cost;
}
}
$product = new Product("ABC123", 29.99);
echo $product->sku;
输出:
ABC123要点:只读属性在属性层面提供不可变性。它们非常适合用于标识对象或创建后不应更改的数据,既保留了运行时初始化的灵活性,又能防止意外修改。
挑战
简单让我们构建一个不可变的配置系统,使用只读属性确保关键设置在初始化后不会被意外更改。
你将创建两个文件,它们会协同管理应用程序配置:
Config.php:定义一个Config类,用于表示具有不可变设置的应用程序配置。这个类应有三个公共只读属性:string $appName、string $version和int $maxConnections。使用构造函数属性提升,在一个简洁的构造函数定义中声明并初始化这三个只读属性。添加一个getInfo()方法,返回格式为"[appName] v[version] (max: [maxConnections] connections)"的字符串。main.php:引入 Config 类文件。你会收到三个输入:应用程序名称、版本,以及最大连接数(这是一个需要转换为整数的字符串)。使用这些值创建一个Config对象。第一行打印getInfo()的结果。然后通过直接访问每个只读属性,逐行打印它们的值:应用程序名称、版本和最大连接数。
只读属性可以确保配置创建后,其值就会固定不变,非常适合在应用程序运行期间应保持不变的设置。请注意,构造函数属性提升与只读属性结合使用,可以非常简洁地定义不可变值对象。
你的输出应先显示格式化的信息字符串,然后逐行显示每个属性的值,以此展示只读属性仍可在类外部读取。
亲手试试
<?php
require_once 'Config.php';
// 读取输入
$appName = trim(fgets(STDIN));
$version = trim(fgets(STDIN));
$maxConnections = intval(trim(fgets(STDIN)));
// TODO:使用输入值创建一个 Config 对象
// TODO:输出 getInfo() 的结果
// TODO:将每个 readonly 属性分别输出在单独一行:
// - 应用名称
// - 版本
// - 最大连接数
?>这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: PHP 在线编译器