[Osaka/Yokohama] Looking for infrastructure/server side engineers!

[Osaka/Yokohama] Looking for infrastructure/server side engineers!

[Deployed by over 500 companies] AWS construction, operation, maintenance, and monitoring services

[Deployed by over 500 companies] AWS construction, operation, maintenance, and monitoring services

[Successor to CentOS] AlmaLinux OS server construction/migration service

[Successor to CentOS] AlmaLinux OS server construction/migration service

[For WordPress only] Cloud server “Web Speed”

[For WordPress only] Cloud server “Web Speed”

[Cheap] Website security automatic diagnosis “Quick Scanner”

[Cheap] Website security automatic diagnosis “Quick Scanner”

[Low cost] Wasabi object storage construction and operation service

[Low cost] Wasabi object storage construction and operation service

[Reservation system development] EDISONE customization development service

[Reservation system development] EDISONE customization development service

[Registration of 100 URLs is 0 yen] Website monitoring service “Appmill”

[Registration of 100 URLs is 0 yen] Website monitoring service “Appmill”

[Compatible with over 200 countries] Global eSIM “beSIM”

[Compatible with over 200 countries] Global eSIM “beSIM”

[Compatible with Chinese corporations] Chinese cloud / server construction, operation and maintenance

[Compatible with Chinese corporations] Chinese cloud / server construction, operation and maintenance

[YouTube] Beyond official channel “Biyomaru Channel”

[YouTube] Beyond official channel “Biyomaru Channel”

PHP 8.2 で追加された ReadOnly Class を触ってみた!

こんにちは!システム開発部の小出です!

12月8日に PHP 8.2 がリリースされました!

本日は、PHP 8.2 で追加された読み取り専用クラスに関して書いていきます。

それでは早速みていきましょう。

読み取り専用クラス(readonly class)

PHP 8.1 ではプロパティに対して readonly 修飾子を設定することが可能になりましたが、

PHP 8.2 ではクラスに対して readonly 修飾子を設定することが可能になりました。

<?php

readonly class SekarakuBlog
{ 
  public string $title; 
}

上記によって、クラス内の全てのプロパティが readonly になります。

<?php

readonly class SekarakuBlog
{
  public string $title;

  public function __construct()
  {
    $this->title = 'test Title';
  }
}

$test = new SekarakuBlog();
$test->title = 'Change Title'; // Fatal error: Uncaught Error: Cannot modify readonly property SekarakuBlog::$title
$test->content = 'content'; // Fatal error: Uncaught Error: Cannot create dynamic property SekarakuBlog::$content

readonly クラス内のプロパティを書き換えようとすると下記のエラーがでることが確認できます。

Fatal error: Uncaught Error: Cannot modify readonly property SekarakuBlog::$title

さらには、動的プロパティの作成も禁止されます。

動的プロパティを作成しようとすると下記のようなエラーが発生します。

Fatal error: Uncaught Error: Cannot create dynamic property SekarakuBlog::$content

また、PHP 8.2 から動的プロパティが非推奨になりました。

#[AllowDynamicProperties] 属性を記述することで、動的プロパティを引き続き使用することができます。

しかし、readonly クラス内で #[AllowDynamicProperties] を使用することは禁止されており、readonly クラスで #[AllowDynamicProperties] を使用しようとすると、下記のようなエラーが発生します。

<?php
#[AllowDynamicProperties]
readonly class SekarakuBlog {}

// Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class SekarakuBlog

<?php readonly class SekarakuBlog 
{ 
  public $title;

  public function __construct() 
  { 
   $this->title = 'test Title'; 
  } 
} 

$test = new SekarakuBlog(); 
// Fatal error: Readonly property SekarakuBlog::$title must have type

プロパティに型を定義していない場合にもエラーが発生するので注意しましょう。

継承

readonly クラスを readonly クラスで継承をすることは可能ですが、

readonly クラスを readonly ではないクラスで継承をしたり、readonly ではないクラスを readonly のクラスで継承をすることは禁止されております。

# 下記は OK

readonly class SekarakuBlog {}
readonly class ExtendSekaraku extends SekarakuBlog {}

# 下記はNG
class SekarakuBlog {}
readonly class ExtendSekaraku extends SekarakuBlog {}
// Fatal error: Readonly class ExtendSekaraku cannot extend non-readonly class SekarakuBlog

readonly class SekarakuBlog {}
class ExtendSekaraku extends SekarakuBlog {}
// Fatal error: Non-readonly class ExtendSekaraku cannot extend readonly class SekarakuBlog

下記メソッドを使用することで、readonly クラスか否かも確認できるようになりました。

readonly class SekarakuBlog
{}

$refrectionClass = new ReflectionClass('SekarakuBlog');
$refrection->isReadOnly(); // true

final クラス修飾子との違い

read only クラスと final クラス修飾子の違いに関しても少し触れます。

read only クラスは上記で説明してきた通り、read only クラス同士の継承は可能でしたが、final クラス修飾子をしたクラスは

クラスの拡張を行うことができません。

ちなみに、クラスの拡張も、値の書き換えも行いたく無い場合は下記の記述をすることができます。

<?php
final readonly class Sekaraku
{
  public string $hoge;

  public function __construct()
  {
    $this->hoge = 'hoge';
  }
}

$test = new Sekaraku();
$test->hoge = 'test';
// Fatal error: Uncaught Error: Cannot modify readonly property Sekaraku::$hoge in /var/www/html/docker/php/finalreadonly.php:17

readonly class Lab extends Sekaraku
{}

$test2 = new Lab();
// Fatal error: Class Lab cannot extend final class Sekaraku in /var/www/html/docker/php/finalreadonly.php on line 20

メリット

readonly クラスを使用することで、プロパティ毎に readonly 修飾子を設定する必要がなく手間が省けます。

一度設定した値は書き換えることができなくなり、動的プロパティも禁止することができるのでより堅牢なコードを書くことができそうですね。

まとめ

今回は PHP 8.2 で追加された機能は他にもありましたが、全体的に細かい追加機能が多かった印象です。

個人的には動的プロパティが非推奨になった点は、今後の PHP ではかなり大きいと思いました。

(クラスのプロパティをクラス外で宣言したときに、どこでそのプロパティが宣言されているか分からなくなりますし

デバッグの効率が落ちると考えているからです。)

使用している方も多いかと思いますので、バージョンを上げる際には注意が必要そうです。

また、紹介できればと思います!

それでは良い PHP ライフを!

この記事がお役に立てば【 いいね 】のご協力をお願いいたします!
7
読み込み中...
7 票, 平均: 1.00 / 17
1,075
X facebook はてなブックマーク pocket
[2024.6.30 CentOS support ended] CentOS server migration solution

[2024.6.30 CentOS support ended] CentOS server migration solution

[2025.6.30 Amazon Linux 2 support ended] Amazon Linux server migration solution

[2025.6.30 Amazon Linux 2 support ended] Amazon Linux server migration solution

[Osaka/Yokohama] Actively recruiting infrastructure engineers and server side engineers!

[Osaka/Yokohama] Actively recruiting infrastructure engineers and server side engineers!

The person who wrote this article

About the author

Shōgo Koide

Born in Osaka Prefecture. He is an engineer who loves saunas. On his days off, he goes to the sauna and communicates with the universe. She holds an in-house meeting called Asamokukai every weekday morning from 8:30 to 9:30, and is the chairperson of the Asamokukai. In his work, he is mainly responsible for development in PHP.