Menu
CoddyTech

只读属性(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

要点:只读属性在属性层面提供不可变性。它们非常适合用于标识对象或创建后不应更改的数据,既保留了运行时初始化的灵活性,又能防止意外修改。

challenge icon

挑战

简单

让我们构建一个不可变的配置系统,使用只读属性确保关键设置在初始化后不会被意外更改。

你将创建两个文件,它们会协同管理应用程序配置:

  • 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 属性分别输出在单独一行:
// - 应用名称
// - 版本
// - 最大连接数

?>
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: PHP 在线编译器