摘要:實(shí)驗(yàn)一個抽象類,有個方法,通過延遲靜態(tài)綁定實(shí)例化并返回。這里如果把注釋打開,打印的就是重寫的值如果把抽象類改成普通類,改成的方式實(shí)例化,結(jié)果就不同了,打印的屬性都是各自類的屬性。
(原文地址,內(nèi)容以原文為準(zhǔn),可能修改或者補(bǔ)充:https://blog.tanteng.me/2017/...)
關(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 并沒有生效,但實(shí)際上在調(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; }
位于 vendorlaravelframeworksrcIlluminateDatabaseEloquentModel.php Line 557.
因?yàn)?Laravel 框架的這個 Model 類是一個 abstract 類型,PHP 中 abstract 類可以用 new static 后期靜態(tài)綁定的方式實(shí)例化,而 create 方法里 $model = new static($attributes) 實(shí)際上就是重新實(shí)例化了并返回,而調(diào)用者 Model 類沒有定義 table 屬性,所以這個時候 $this->table 是沒有值的。
解決辦法是用 save 方法即可,如圖所示。實(shí)際上 create 方法也調(diào)用了 save 方法。
實(shí)驗(yàn)一個抽象類 A,有個 create 方法,通過延遲靜態(tài)綁定實(shí)例化并返回。B 類繼承 A,test 方法中修改父類的 name 屬性。
name = "Tony Tan"; return $this; } } $obj1 = (new B)->test(); $obj2 = (new B)->test()->create(); var_dump($obj1); var_dump($obj2);
結(jié)果顯示 $obj1 和 $obj2 這兩個實(shí)例都是 B 的實(shí)例,調(diào)用 test 方法屬性 name 改變了,但是調(diào)用 create 方法后,name 屬性并沒有改變。這也就是在本文中說的在 Lavarel 中遇到的場景。(這里如果把注釋打開,打印的 name 就是重寫的值)
如果把抽象類 A 改成普通類,new static 改成 new self 的方式實(shí)例化,結(jié)果就不同了,打印的屬性 name 都是各自類的屬性。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/25623.html
摘要:判斷是否存在構(gòu)造函數(shù),不存在直接實(shí)例化,存在則通過來獲取輸入函數(shù),并有相應(yīng)的方法解決依賴參數(shù)問題,實(shí)現(xiàn)依賴注入。 Laravel 框架關(guān)鍵技術(shù)解析·讀書筆記(一) 第一章 入口文件 請求訪問的入口文件,主要完成幾部分工作,分別是: 自動加載函數(shù)的添加 服務(wù)器實(shí)例化與服務(wù)注冊 路由加載 請求實(shí)例化與路由分發(fā) 相應(yīng)生成與發(fā)送 其中,自動加載函數(shù)用于包含引用文件,改文件是composer...
摘要:最近在維護(hù)一個三年前的舊代碼,用的是框架。單元測試和語言并發(fā)控制實(shí)際上是個蛋疼的問題,夸張一點(diǎn)說,當(dāng)時的并不能特別輕松地實(shí)現(xiàn)并發(fā),甚至不能實(shí)現(xiàn)并發(fā)。語言的功能之一就是自帶單元測試。用語言之前,我的習(xí)慣是不寫單元測試。 最近在維護(hù)一個三年前的舊代碼,用的是laravel框架。 從某些方面來講,這個代碼算是比較標(biāo)準(zhǔn)為了實(shí)現(xiàn)在規(guī)定的時間內(nèi)完成相關(guān)功能,同時程序員水平不高、經(jīng)過大量優(yōu)化之后,變...
摘要:可以為服務(wù)提供者的方法設(shè)置類型提示。方法將在所有其他服務(wù)提供者均已注冊之后調(diào)用。所有服務(wù)提供者都在配置文件中注冊??梢赃x擇推遲服務(wù)提供者的注冊,直到真正需要注冊綁定時,這樣可以提供應(yīng)用程序的性能。 本文最早發(fā)布于 Rootrl的Blog 導(dǎo)言 Laravel是一款先進(jìn)的現(xiàn)代化框架,里面有一些概念非常重要。在上手Laravel之前,我認(rèn)為先弄懂這些概念是很有必要的。你甚至需要重溫下PHP...
摘要:的核心概念包括服務(wù)容器服務(wù)提供者門面契約。所有服務(wù)提供者都需要繼承類??梢詾榉?wù)提供者的方法設(shè)置類型提示。方法將在所有其他服務(wù)提供者均已注冊之后調(diào)用。同樣會整理成思維導(dǎo)圖的形式以方便記憶與回顧。 showImg(https://segmentfault.com/img/remote/1460000010771201); Laravel 的核心概念包括:服務(wù)容器、服務(wù)提供者、門面(Fac...
摘要:服務(wù)提供者先看看定義服務(wù)提供者是所有應(yīng)用程序啟動的中心所在。通過本文,希望大家能夠了解服務(wù)提供者,,和實(shí)際調(diào)用的類的實(shí)例之間的關(guān)系。 以 Laravel 自帶的文件系統(tǒng)為例,在 config/app.php 的配置文件的 providers 數(shù)組中,注冊了一個服務(wù)提供者: IlluminateFilesystemFilesystemServiceProvider::class, 在 a...
閱讀 2999·2023-04-25 21:23
閱讀 3042·2021-09-22 15:24
閱讀 870·2019-08-30 12:55
閱讀 2104·2019-08-29 18:42
閱讀 2615·2019-08-29 16:27
閱讀 955·2019-08-26 17:40
閱讀 2189·2019-08-26 13:29
閱讀 2614·2019-08-26 11:45