淺談Laravel中的一個(gè)后期靜態(tài)綁定
關(guān)于 PHP 的 new static 延遲靜態(tài)綁定,或者叫后期靜態(tài)綁定,在 Laravel 中遇到一個(gè)使用上的問(wèn)題。如下,在 Laravel 中調(diào)用 Model 新增數(shù)據(jù)的時(shí)候,首先給 Model 加了一個(gè)獲取分表的方法:
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; }
從報(bào)錯(cuò)日志中發(fā)現(xiàn) $this->table 并沒有生效,但實(shí)際上在調(diào)用 create 方法之前打印表名的時(shí)候是期望的值,這里調(diào)用 create 方法為什么 $this->table 沒有被重置呢?
這里 $this->message 是一個(gè)繼承 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.
因?yàn)?Laravel 框架的這個(gè) Model 類是一個(gè) abstract 類型,PHP 中 abstract 類可以用 new static 后期靜態(tài)綁定的方式實(shí)例化,而 create 方法里 $model = new static($attributes) 實(shí)際上就是重新實(shí)例化了并返回,而調(diào)用者 Model 類沒有定義 table 屬性,所以這個(gè)時(shí)候 $this->table 是沒有值的。
解決辦法是用 save 方法即可,如圖所示。實(shí)際上 create 方法也調(diào)用了 save 方法。
實(shí)驗(yàn)
一個(gè)抽象類 A,有個(gè) create 方法,通過(guò)延遲靜態(tài)綁定實(shí)例化并返回。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 這兩個(gè)實(shí)例都是 B 的實(shí)例,調(diào)用 test 方法屬性 name 改變了,但是調(diào)用 create 方法后,name 屬性并沒有改變。 這也就是在本文中說(shuō)的在 Lavarel 中遇到的場(chǎng)景。 (這里如果把注釋打開,打印的 name 就是重寫的值)
如果把抽象類 A 改成普通類,new static 改成 new self 的方式實(shí)例化,結(jié)果就不同了,打印的屬性 name 都是各自類的屬性。
參考鏈接
PHP中new self()和new static()的區(qū)別
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Laravel 5框架學(xué)習(xí)之模型、控制器、視圖基礎(chǔ)流程
- Laravel模型事件的實(shí)現(xiàn)原理詳解
- laravel學(xué)習(xí)筆記之模型事件的幾種用法示例
- 使用laravel的Eloquent模型如何獲取數(shù)據(jù)庫(kù)的指定列
- Laravel 模型關(guān)聯(lián)基礎(chǔ)教程詳解
- Laravel使用模型實(shí)現(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)文章
PHP開源開發(fā)框架ZendFramework使用中常見問(wèn)題說(shuō)明及解決方案
Zend Framework(簡(jiǎn)寫ZF)是由 Zend 公司支持開發(fā)的完全基于 PHP5 的開源PHP開發(fā)框架,可用于開發(fā) Web 程序和服務(wù),ZF采用 MVC(Model–View-Controller) 架構(gòu)模式來(lái)分離應(yīng)用程序中不同的部分方便程序的開發(fā)和維護(hù)。2014-06-06php array_values 返回?cái)?shù)組的所有值詳解及實(shí)例
這篇文章主要介紹了php array_values 返回?cái)?shù)組的所有值詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2016-11-11ThinkPHP快速入門實(shí)例教程之?dāng)?shù)據(jù)分頁(yè)
這篇文章主要介紹了ThinkPHP快速入門實(shí)例教程的數(shù)據(jù)分頁(yè)實(shí)現(xiàn)過(guò)程,需要的朋友可以參考下2014-07-07destoon供應(yīng)信息title調(diào)用出公司名稱的方法
這篇文章主要介紹了destoon供應(yīng)信息title調(diào)用出公司名稱的方法,非常具有實(shí)用價(jià)值的一個(gè)技巧,需要的朋友可以參考下2014-08-08解決laravel 表單提交-POST 異常的問(wèn)題
今天小編就為大家分享一篇解決laravel 表單提交-POST 異常的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-10-10Yii框架實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的CURD操作示例
這篇文章主要介紹了Yii框架實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的CURD操作,結(jié)合實(shí)例形式分析了Yii框架連接數(shù)據(jù)庫(kù)與CURD增刪改查等常見操作技巧,需要的朋友可以參考下2019-09-09PHP實(shí)現(xiàn)簡(jiǎn)單計(jì)算器小程序
這篇文章主要為大家詳細(xì)介紹了PHP實(shí)現(xiàn)簡(jiǎn)單計(jì)算器小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12Codeigniter通過(guò)SimpleXML將xml轉(zhuǎn)換成對(duì)象的方法
這篇文章主要介紹了Codeigniter通過(guò)SimpleXML將xml轉(zhuǎn)換成對(duì)象的方法,涉及Codeigniter操作XML文件的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-03-03