淺談Laravel中的一個后期靜態(tài)綁定
關(guān)于 PHP 的 new static 延遲靜態(tài)綁定,或者叫后期靜態(tài)綁定,在 Laravel 中遇到一個使用上的問題。如下,在 Laravel 中調(diào)用 Model 新增數(shù)據(jù)的時候,首先給 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 是沒有值的。

解決辦法是用 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 都是各自類的屬性。
參考鏈接
PHP中new self()和new static()的區(qū)別
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Laravel 5框架學(xué)習(xí)之模型、控制器、視圖基礎(chǔ)流程
- Laravel模型事件的實現(xiàn)原理詳解
- laravel學(xué)習(xí)筆記之模型事件的幾種用法示例
- 使用laravel的Eloquent模型如何獲取數(shù)據(jù)庫的指定列
- Laravel 模型關(guān)聯(lián)基礎(chǔ)教程詳解
- Laravel使用模型實現(xiàn)like模糊查詢的例子
- Laravel模型間關(guān)系設(shè)置分表的方法示例
- Laravel 關(guān)聯(lián)模型-關(guān)聯(lián)新增和關(guān)聯(lián)更新的方法
- Laravel關(guān)系模型指定條件查詢方法
- laravel框架模型中非靜態(tài)方法也能靜態(tài)調(diào)用的原理分析
相關(guān)文章
Yii2 RESTful中api的使用及開發(fā)實例詳解
這篇文章主要介紹了Yii2 RESTful中api的使用及開發(fā)實例詳解的相關(guān)資料,需要的朋友可以參考下2016-07-07
Ajax實時驗證用戶名/郵箱等是否已經(jīng)存在的代碼打包
一個網(wǎng)站采用Ajax技術(shù),不僅可以改善網(wǎng)站的用戶體驗性,而且大大節(jié)約了寶貴的帶寬,減輕了服務(wù)器負(fù)荷(不再需要交互整個網(wǎng)頁內(nèi)容,而是局部)。2011-12-12
PHP中把數(shù)據(jù)庫查詢結(jié)果輸出為json格式簡單實例
這篇文章主要介紹了PHP中把數(shù)據(jù)庫查詢結(jié)果輸出為json格式簡單實例,本文直接給出示例代碼,都是非?;A(chǔ)的寫法,大家應(yīng)該一看就明白,需要的朋友可以參考下2015-04-04
Laravel 5框架學(xué)習(xí)之Blade 簡介
本文給大家?guī)淼氖荓aravel5框架學(xué)習(xí)系列文章的第4篇,主要向大家簡單介紹下Blade,為什么要介紹它呢,因為laravel的模版引擎采用了blade模版引擎,so....2015-04-04

