首頁  >  文章  >  後端開發  >  淺析Laravel的後期靜態綁定

淺析Laravel的後期靜態綁定

*文
*文原創
2018-01-03 15:25:431515瀏覽

本文主要介紹了淺談Laravel中的一個後期靜態綁定,分享給大家做個參考。希望對大家有幫助。

關於 PHP  的 new static 延遲靜態綁定,或稱為後期靜態綁定,在 Laravel 遇到一個使用上的問題。如下,在Laravel 中呼叫Model 新增資料的時候,先為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;
}

從報錯日誌中發現$this->table 並沒有生效,但實際上在調用create 方法之前打印表名的時候是期望的值,這裡調用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 後期靜態綁定的方式實例化,而create 方法裡$model = new static($ attributes) 其實就是重新實例化了並傳回,而呼叫者Model 類別沒有定義table 屬性,所以這個時候$this->table 是沒有值的。

解決方法是用 save 方法即可,如圖所示。實際上 create 方法也呼叫了 save 方法。

實驗

一個抽象類別 A,有個 create 方法,透過延遲靜態綁定實例化並傳回。 B 類別繼承 A,test 方法中修改父類別的 name 屬性。

<?php
 
abstract class A
{
  protected $name = "tanteng";
 
  public static function create()
  {
    return new static();
  }
}
 
class B extends A
{
  //protected $name = &#39;纸牌屋弗兰克&#39;;
 
  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 方法屬性 name 改變了,但在呼叫 create 方法後,name 屬性並沒有改變。 這也就是本文所說的在 Lavarel 中遇到的場景。 (這裡如果把註解打開,印出來的name 就是重寫的值)

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

相關推薦:

探究Laravel的中間件是如何實現的

Laravel優化分割路由檔案

laravel編寫APP介面(API)

以上是淺析Laravel的後期靜態綁定的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn