Atsulabo
@Atsulabo (アツ)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

クラスで定義済のプロパティに__getメソッドが使えてしまう?

Q&A

Closed

解決したいこと

まずはコードを出します。
クラスで未定義のプロパティaに1を代入しようとするコードです。
ちなみにPHP5上級試験問題集[PJO-200]の初版、p110の解説に載っているコードです。

index.php
class X {
function __set($name,$value){
    echo $name, 'に', $value, 'を書き込み',"\n";
  }
  function __get($name){
    echo $name, を読み取り,"\n";
  }
}
$x = new X;
$x->a = 1;
$b = $x->a;

出力は問題集に書かれてあるとおり、
「aに1を書き込み
aを読み取り」

となります(実際に書いて確認済)。

しかし、ここで、疑問があります。
まずそもそも、$x->a = 1;の時点で、
クラスXのメソッド__setが呼び出されるはずで、
この時点で、aは定義済となるはずです。
したがって、ここで__getメソッドは呼び出せないはずです。
(__getはそもそも未定義のプロパティにアクセスしようとしたときにコールされるため)

それなのになぜこの通り出力されているのでしょうか?

発生している問題・エラー

なし

該当するソースコード

上記にあり

自分で試したこと

上記では\$valueを出していないので、試しにこれを出力しようとすると
未定義で空白のままでした。
これが関係あるのかどうかわかりませんが。。。

0

1Answer

まずそもそも、$x->a = 1;の時点で、
クラスXのメソッド__setが呼び出されるはずで、
この時点で、aは定義済となるはずです。

__set が呼び出されるところまでは合っていますが、呼び出されても a は定義されません。これは var_dump(property_exists($x, 'a')); と書けば確認することができます。

__set が呼び出されたときにプロパティを定義するには以下のようにします。

function __set($name, $value) {
    echo $name, 'に', $value, 'を書き込み',"\n";
    $this->{$name} = $value; // ここでプロパティを定義
}
1Like

Comments

  1. @Atsulabo

    Questioner

    そうなんですね!!
    ありがとうございます。疑問が氷解しました。
    他の問題と合わせてすごく理解できました。
    @uasiさん、重ね重ねですが、ありがとうございました!!

Your answer might help someone💌