溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Laravel中怎么實現(xiàn)后期靜態(tài)綁定

發(fā)布時間:2021-07-19 14:36:25 來源:億速云 閱讀:146 作者:Leah 欄目:開發(fā)技術(shù)

Laravel中怎么實現(xiàn)后期靜態(tài)綁定,針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

首先給 Model 加了一個獲取分表的方法:

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 方法是在 Model 里定義的獲取分表的方法:

public function setTable($table)
{
  $this->table = $table;
  return $this;
}

從報錯日志中發(fā)現(xiàn) $this->table 并沒有生效,但實際上在調(diào)用 create 方法之前打印表名的時候是期望的值,這里調(diào)用 create 方法為什么 $this->table 沒有被重置呢?

這里 $this->message 是一個繼承 Model 類的模型類,其中 create 方法:

public static function create(array $attributes = [])
{
  $model = new static($attributes);
 
  $model->save();
 
  return $model;
}

位于 vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php Line 557.

因為 Laravel 框架的這個 Model 類是一個 abstract 類型,PHP 中 abstract 類可以用 new static 后期靜態(tài)綁定的方式實例化,而 create 方法里 $model = new static($attributes) 實際上就是重新實例化了并返回,而調(diào)用者 Model 類沒有定義 table 屬性,所以這個時候 $this->table 是沒有值的。

Laravel中怎么實現(xiàn)后期靜態(tài)綁定

解決辦法是用 save 方法即可,如圖所示。實際上 create 方法也調(diào)用了 save 方法。

實驗

一個抽象類 A,有個 create 方法,通過延遲靜態(tài)綁定實例化并返回。B 類繼承 A,test 方法中修改父類的 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);

結(jié)果顯示 $obj1 和 $obj2 這兩個實例都是 B 的實例,調(diào)用 test 方法屬性 name 改變了,但是調(diào)用 create 方法后,name 屬性并沒有改變。 這也就是在本文中說的在 Lavarel 中遇到的場景。 (這里如果把注釋打開,打印的 name 就是重寫的值)

如果把抽象類 A 改成普通類,new static 改成 new self 的方式實例化,結(jié)果就不同了,打印的屬性 name 都是各自類的屬性。

關(guān)于Laravel中怎么實現(xiàn)后期靜態(tài)綁定問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI