この記事は主にLaravelにおける後期静的バインディングについての簡単な議論を紹介し、参考として皆さんに共有します。お役に立てれば幸いです。
PHP の新しい静的遅延静的バインディング、または遅延静的バインディングに関して、Laravel で使用上の問題が発生しました。以下のように、Laravel でモデルを呼び出して新しいデータを追加するときは、まずサブテーブルを取得するメソッドをモデルに追加します:
protected function addToMessage($msgType, $userID, $commentID, $replyCommentID, $replyUserID, $gameID) { if (!$userID) { return false; } $table = 't_message_' . hashID($userID, 100); $this->message->setTable($table)->create([ 'msg_type' => $msgType, 'user_id' => $userID, 'comment_id' => $commentID, 'reply_comment_id' => $replyCommentID, 'reply_user_id' => $replyUserID, 'game_id' => $gameID, 'is_read' => 0, 'created_at' => date('Y-m-d H:i:s'), ]); return true; }
ここでの setTable メソッドは、サブテーブルを取得するためにモデルに定義されているメソッドです:
public function setTable($table) { $this->table = $table; return $this; }
エラーログから $this->table が有効になっていないことが分かりますが、実際には create メソッドを呼び出す前にテーブル名が出力されると、それが期待値になっています。なぜ $this->table なのでしょうか。ここで create メソッドが呼び出されたときにリセットされないのでしょうか?
ここで $this->message は Model クラスを継承するモデルクラスで、create メソッド:
public static function create(array $attributes = []) { $model = new static($attributes); $model->save(); return $model; }
は、vendorlaravelframeworksrcIlluminateDatabaseEloquentModel.php の 557 行目にあります。
Laravel フレームワークの Model クラスは抽象型であるため、 、PHP の抽象クラス new static late static binding を使用してインスタンス化でき、create メソッドの $model = new static($attributes) は実際に再インスタンス化されて返され、呼び出し元の Model クラスはテーブル属性を定義しませんしたがって、現時点では $this->table には値がありません。
解決策は、図に示すように、saveメソッドを使用することです。実際、create メソッドは save メソッドも呼び出します。
実験
抽象クラス A には create メソッドがあり、このメソッドは遅延静的バインディングを通じてインスタンス化されて返されます。クラス B は A を継承し、親クラスの name 属性がテスト メソッドで変更されます。
<?php abstract class A { protected $name = "tanteng"; public static function create() { return new static(); } } class B extends A { //protected $name = '纸牌屋弗兰克'; public function test() { $this->name = "Tony Tan"; return $this; } } $obj1 = (new B)->test(); $obj2 = (new B)->test()->create(); var_dump($obj1); var_dump($obj2);
結果は、$obj1 と $obj2 の両方のインスタンスが B のインスタンスであることを示しています。test メソッドの呼び出しによって属性名が変更されましたが、create メソッドの呼び出し後、name 属性は変更されていません。 これは、この記事で言及したラヴァレルで遭遇したシーンです。 (ここでアノテーションがオンになっている場合、出力される名前は書き換えられた値になります)
抽象クラス A を通常のクラスに変更し、インスタンス化のために新しい static を新しい self に変更すると、結果は異なります。出力される属性名は各クラスのプロパティになります。
関連する推奨事項:
Laravelのミドルウェアがどのように実装されているかを調べる
以上がLaravel の後期静的バインディングの簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。