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