Menu
Coddy logo textTech

Readonlyプロパティ(PHP 8.1)

CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 19/91。

PHP 8.1ではreadonlyプロパティが導入されました。これは一度だけ代入でき、その後は変更できません。定数とは異なり、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

一度代入すると、readonly property を変更しようとした際にエラーが発生します。これらは、ID や作成時のタイムスタンプのように、object の存続期間全体を通じて一定であるべき値に最適です。

Readonly properties には型宣言が必要で、宣言元の class 内(通常は constructor 内)から一度だけ代入できます。通常の properties とは異なり、宣言時にデフォルト値を指定することはできません。あらゆる可視性修飾子で使用できます。

<?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

重要なポイント: readonly properties は property レベルで不変性を提供します。object を識別するデータや、作成後に変更すべきでないデータに最適であり、実行時初期化の柔軟性と、誤った変更を防ぐ安全性を兼ね備えています。

challenge icon

チャレンジ

簡単

初期化後に重要な設定が誤って変更されないよう、readonly プロパティを使用した不変の設定システムを構築しましょう。

アプリケーション設定を管理するために連携して動作する2つのファイルを作成します。

  • Config.php:不変の設定を持つアプリケーション設定を表す Config クラスを定義します。このクラスには、3つの public readonly プロパティ、string $appNamestring $versionint $maxConnections を持たせます。コンストラクター・プロモーションを使用して、3つすべての readonly プロパティを簡潔な1つのコンストラクター定義内で宣言および初期化します。getInfo() メソッドを追加し、"[appName] v[version] (max: [maxConnections] connections)" 形式の string を返すようにします。
  • main.php:Config クラスのファイルを読み込みます。3つの入力値、つまりアプリ名、version、最大接続数(int に変換する必要がある string)を受け取ります。これらの値を使用して Config object を作成します。1行目に getInfo() の結果を Print します。その後、readonly プロパティに直接アクセスして、それぞれを個別の行に Print します。つまり、アプリ名、version、max 接続数を出力します。

readonly プロパティにより、configuration が作成されるとその values が固定され、アプリケーションの実行中ずっと一定に保つべき設定に最適です。constructor promotion と readonly を組み合わせることで、不変の値 object を非常に簡潔に定義できる点に注目してください。

出力には、formatted な info string の後に各 property の値が表示され、readonly プロパティをクラスの外部から読み取ることもできることが示されます。

REQUIRED OUTPUT FORMAT: [Your translated content here]

自分で試してみよう

<?php

require_once 'Config.php';

// 入力を読み取る
$appName = trim(fgets(STDIN));
$version = trim(fgets(STDIN));
$maxConnections = intval(trim(fgets(STDIN)));

// TODO: 入力値を使用してConfigオブジェクトを作成する

// TODO: getInfo()の結果を出力する

// TODO: 各readonlyプロパティをそれぞれ1行で出力する:
// - アプリ名
// - バージョン
// - 最大接続数

?>
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: PHPオンラインコンパイラ