Laravelは(というかORMのEloquentは)
$phone->user とか未定義のプロパティにアクセスした際に走る __get, __set をオーバーロードして
Laravelのあの魔化不思議な動きを実装してる
具体的には、$phone->user とした時点で以下の動作が走る
プロパティ user の存在をチェック (PHPの動き)
- userプロパティが存在したら そのまま userプロパティの内容を戻す これはPHPの言語仕様でオーバーロードとかは一切できない
- userプロパティが存在しなかったら __get マジックメソッドが走る
で マジックメソッドはLaravel側でオーバーロードされていて 以下の処理をしている
- リレーションの有無をチェック
- リレーションが存在したら user_id の存在を確認する
- user_id も存在しなかったら userプロパティに null をセットした上で、そのnull を戻す
- user_id が存在して値が入っていたら select * from user where user_id = 1 が走った上で
userプロパティには userオブジェクトが格納し、その上でuserオブジェクトを戻す
キモは すでに存在するいプロパティにアクセスした時に効かせられるフックはPHPに存在しない って話。
ケース2では、すでに一度 $dummy = $phone->user; でアクセスし、この時点でuserプロパティが 内容null で作られてしまってる。
user_id をいじったら user の内容も連動して変わるってのは錯覚だって話なのよね。
初回だけマジックメソッドの効果でそう動いてるように見えるから混乱する。
user, user_id が共にセットされた後、つまりプロパティが作られた後は user_id を変えただけでは userの内容は自動的には変わらない。
さっき言ったように、すでに存在するプロパティにアクセスした時に効かせられるフックはPHPに存在しないから。
だから
$user = User::find(2);
$phone->user = $user;
とした後に、 $phone->user_id = 1; としても $phone->user の内容は自動的には変わらないし変えることも出来ない。
ただ、saveとか一旦すると user_id の値がDBに保存されて、次 またuser を再取得するときは user_id 1 のオブジェクトが戻されるため
いかにも自動的に変わったように錯覚してしまう。
[PHPフレームワーク]Laravel
■ このスレッドは過去ログ倉庫に格納されています
355nobodyさん
2015/02/22(日) 02:00:36.90ID:???■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 【涙の理由】チュニジア代表DFが怒り爆発「日本代表を見てみろ」…W杯敗退決定、チーム作りに不満「無理に決まっている」 [王子★]
- アルバイト女性(30)と小学生女児(10) 練炭が置かれた車内で発見される [お断り★]
- 【野球】セ・リーグ DB 1-2 T [6/21] 阪神3連勝 高橋遥人1失点完投、大山・高寺タイムリー DeNA連敗 [鉄チーズ烏★]
- 「悲しいの類義語は?」→「ぴえん」現役高校生の語彙力不足に国語講師が危機感を抱くワケ。「自分が何を考えてるかわからない」 [少考さん★]
- 高市内閣支持、発足以来最低の55% ★2 [どどん★]
- 【サッカーW杯】4-0 日本代表・森保ジャパン、チュニジアに歴史的4発大勝 アジア勢の1次L連敗を「6」で止めた★5 [ゴアマガラ★]
- 【実況】博衣こよりのえちえち栄冠ナイン2028🧪
- イラン「イスラエルによるレバノン攻撃が続く限り、ホルムズ海峡は開放されない」 [256556981]
- 🏡ふなっていいとも!増刊号🕶(⁠・⁠o⁠・⁠🍬)
- 女さん絶望「息子が不登校になった上、一日中ゲームしてる。ゲームを制限しようとしたら発狂して物を投げて暴れる…どうすればいいの? [257926174]
- 【悲報】世間じゃ神ゲー扱いされてるけど個人的には「つまんねえ……」と思ったゲーム挙げてけ [714769305]
- 【急募】10年、20年後くらいに国内で起きてそうなこと [943688309]