🍣
PHP __get()と__isset()とNull合体演算子と
PHPの __get()
__isset()
そしてNull合体演算子ではまりました。
事象
Laravel環境でEloquentのModelの __get()
を拡張した際にこのような事象にあいました。
<?php
// hogeは存在しないプロパティ
// __getで動的に値を返している
echo $obj->hoge; // -> 'hoge'
echo $obj->hoge ?? 'fuga'; // -> 'fuga'
$obj->hoge
は null
ではないのにNull合体演算子で null
判定される?
という感じで悩みました。
Null合体演算子
Null合体演算子 ??
はPHP7から入った新機能です。
isset($hoge) ? $hoge : 'fuga'
が $hoge ?? 'fuga'
と書けます。
つまり今回の事象は isset($obj->hoge) === false
であったということなのです。
__isset()
__isset() は、 isset() あるいは empty() をアクセス不能(protected または private)または存在しないプロパティに対して実行したときに起動します。
存在しないプロパティに対して isset()
empty()
を実行すると __isset()
がコールされるのでそこで適切な値を返さないといけないわけでした。
解決
Illuminate\Database\Eloquent\Model
の __isset
を追いまして、自分用の存在チェックを滑り込ませました。
ということで__get()
を触る時は __isset()
もセットでお願いします。(なるべくマジックメソッド使うべからず)
Discussion