【PHP】PHP8.2リリースと動的なプロパティ生成の非推奨化について

  • 2022年12月9日
  • PHP

 PHP8.2がリリースされました。PHP8.2の大きな変化は動的なプロパティ生成の非推奨化です。他にも一部界隈の方にとっては Random クラスの追加もインパクトが大きそうです。その他は型の拡張などの細かい部分で「あれができたらいいのに」と思えた部分が実装された感じです。

PHP: PHP 8.2.0 Release Announcement
PHP: PHP 8.1.x から PHP 8.2.x への移行 – Manual

 動的なプロパティの非推奨化ですが、次の例の通りです。従来の特別プロパティについての記述がないクラスに動的にプロパティを増やすと非推奨の警告がでます。

<?php
/** 従来の普通のクラス内で定義されていないプロパティをインスタンス化した後に生やすと非推奨の警告が出るようになりました */
class User
{
    public $name;
}
// この非推奨の警告は次の様に出ます
$user            = new User();
$user->last_name = 'Doe'; // Deprecated: Creation of dynamic property User::$last_name is deprecated in xxx.php on line 9

/** stdClass、いわゆる無名の汎用的な空のクラスでは動的にプロパティを生やしても問題ないです。 */
$user            = new stdClass();
$user->last_name = 'Doe'; // 何の警告も発生しない

// stdClass は new stdClass() 以外でも生成されます。よくあるのは json_decode や SQL の結果です。
$user = json_decode('{}', false, JSON_THROW_ON_ERROR);
$user->last_name = 'Doe'; // 何の警告も発生しない

/** PHP8.2 から増えたアトリビュートであるAllowDynamicPropertiesをつけることでも動的にプロパティを生やすことが許されます */
// @see https://www.php.net/manual/ja/class.allow-dynamic-properties.php
#[\AllowDynamicProperties]
class UserWithAllowDynamicProperties
{
    public $name;
}

$user            = new UserWithAllowDynamicProperties();
$user->last_name = 'Doe'; // 何の警告も発生しない

/** マジックメソッドである __set を使う場合も動的にプロパティを生やす様な書き方が許されます */
// @see https://www.php.net/manual/ja/language.oop5.overloading.php#object.set
// 今回の動的なプロパティの作成の非推奨化は厳密にはクラスで宣言されていないプロパティの扱いを非推奨に寄せるものです。
class UserWithSetter
{
    public $name;
    protected array $attr = [];
    public function __set(string $name, $value): void
    {
        $this->attr[$name] = $value;
    }
}

$user            = new UserWithSetter();
$user->last_name = 'Doe'; // 何の警告も発生しない

Online PHP editor | output for nmQkc#上記コードのデモ

 動的なプロパティ生成ですが PHP9.0 になった際に例外が投げられる様になると RFC で予告されています。これによりインスタンスが処理を経たらいつの間にか拡張を後付けされた別物になっている、ということがほぼ起きなくなります。一方で、昔のコードで動かなくなる部分が多そうな変更でもあります。PHP8.2移行へコードを移行する際は特に注意が必要な部分です。一応、全部のクラスに#[\AllowDynamicProperties]をつけるという対応もできますが、PHPstanやIDEなど何かしら自動的に検知できる仕組みを入れてプロパティ定義を明文化する方向で書き換えを行いたいところです。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG