概要
PHP8においてインスタンスの情報を取得するメソッドにget_object_vars
があり、これを使えば引数に渡したインスタンスのもつアクセス可能なプロパティについてArray型で出力してくれる。
これはDTOのようなプロパティ主体で構成されるクラスなんかの共通処理として実装しておけば色々楽になりそうだったので、抽象クラスにget_object_vars($this)
を戻り値として返すようなpublicなメソッドを定義した。(オーバライドせずそのまま使用する用途)
問題
継承先のクラスではprivateのプロパティは「アクセス不能」とみなされ取得できない。
誤解いただきたくないのは、上記のようにインスタンス内部で引数を$thisとして当該メソッドをラップしたメソッドを定義して継承元クラスのインスタンスでは 通常のgetterメソッドと同様にprivateだろうが当然アクセスできる。
<?php class Test1{ public function pp(){ var_dump(get_object_vars($this)); } } class Test2 extends Test1{ public $v1='a'; protected $v2='b'; private $v3='c'; } $t=new Test2; $t->pp(); > array(2) { ["v1"]=> string(1) "a" ["v2"]=> string(1) "b" }
調べるとこれはPHP5で入った変更のようで、継承先のプロパティがprivateであった場合は継承元で定義したget_object_vars()はアクセスできなくなったようだ。
対策
いまのところ思いつくのは以下2つ
- protectedにする。
- 各クラスに直接定義を実装する。
前者が良さそう、個人的にはできるだけプロパティはprivateにしておきたい(でないとOOPの意味が薄くなる)ので。