tp5類的屬性不存在 TP5 模型初始化

2021-10-13 13:42:03 字數 2698 閱讀 7741

前言:

先交代下背景,在乙個專案中,有乙個資料表有水平分表的需求。當時想找到一種方法,把對資料庫的操作,寫到乙個模型裡,通過去換模型屬性中的table來達到**不變操作的資料表變化的效果。

我們都知道,模型要想關聯資料表的話,有兩中方式,第一種就是將模型名和資料表一致。這樣模型就會預設關聯到名字對應的資料表。第二種就是定義模型的 protected $table 來指定表明。我當時就想,有沒有什麼方法,能初始化模型物件的時候將table屬性賦值呢,這個值存在資料庫裡。這樣就可以動態的來控制這個模型關聯的表名了。

模型初始化

基於以上的需求,文件裡的模型初始化引起了我的注意

tp5文件

我感覺這是我要找的東西。緊接著我著手開始測試

首次測試

我根據手冊的寫法,在呼叫父類初始化後面,寫上對table的初始化,那麼現在我們來列印出來例項化的order模型

列印例項化物件

從圖中大家可以發現,table屬性的確已經修改了。然後我就沒有再做更多的測試了,因為我試過手動將table資料改為別的表名,就可以修改模型所關聯的資料表。我想這個table屬性已經有了肯定就沒問題了。

直到我在這個模型裡寫了很多方法後,我想去回來換個表名來試試寫入資料。**的事情出現了。

//我使用包含table屬性的物件去查資料庫。查詢出來的結果,居然任然是原來那個模型名對應的表

return $order->select();

這就很**了,我已經寫好的這麼多**難道都不能用了?

冷靜下來之後,我決定先試試,手動在模型中該表table屬性來試試。

直接修改模型的table屬性

那麼我們再來訪問下呢?

image.png

報錯,報表不存在,這是正確的,因為我沒有建立order_1這個表。不過這也說明了,order模型的確已經和order_1表關聯起來了。這樣就讓我摸不著頭腦了。以前學習物件導向那些理論又浮現在我們腦海裡。我梳理了下思路

order模型中定義table屬性,其實是對父類model中的table的重寫。並且table屬性是乙個protected的。那麼就是說,只有在模型內部或則子類中可以使用和修改

在例項化模型的地方是控制器,也就是類的外部,理論上外部是物件只能讀取和操作類中public的屬性的

可是initialize又是在例項化模型自動觸發的方法,觸發的地方又是在模型的內部。

但是我又是使用$this 又是指代我控制器中的被例項化出來的模型物件。那是不是還是不能訪問被保護的屬性呢?

好了瞎分析完了之後,我決定還是去網上搜尋下,看看有沒有人和我一樣的應用場景。後來我發現,使用模型初始化的人,似乎很少。少數幾篇部落格講解了下。其中有個應用場景和我類似。他在**中是這樣寫的

protected function initialize()

parent::initialize(); // todo: change the autogenerated stub

$this->table('order_1');//假裝這裡名字是從資料庫裡取得

我通過ide的智慧型感知,進入套table方法中,看了下注釋

image.png

看樣子是我需要的方法,可這個方法不是模型基類裡的啊,是在query類當中的。我有些摸不清楚頭腦,但不管怎樣,還是要試一試

為了讓**不報錯,我去增加了乙個order_1表。這一試,嘿嘿,搞定了!

image.png

列印出了我在新錶中的一條資料。哈哈,看來這個思路是可行的

就在我認為這個思路是可行的時候,我在執行我寫好的一些模型方法時,我發現了乙個大坑!!

我就不詳細說我是怎麼發現的了。直接看**

模型裡我還是這麼寫的

protected function initialize()

parent::initialize(); // todo: change the autogenerated stub

$this->table('order_1');//假裝這裡名字是從資料庫裡取得

//控制器裡例項化模型後,呼叫count方法

var_dump($order->count());

var_dump($order->count());die;

結果讓人非常的震驚!

結果同乙個物件,呼叫同乙個方法,結果居然不一樣!我反覆試過都是這樣。我決定將他們的sql列印出來看看有什麼問題

image.png

結果同樣是讓人哭笑不得

image.png

結果模型初始化是一次性的?(黑人問號.jpg)

我當時就覺得是tp5的bug,我要向作者反應!

後來我冷靜下來,還是先把專案問題解決了來再說哦。飯碗要緊。

最終經過我的摸(luan)索(gao) ,我找到解決方案。下面就把**貼出來,但是我確實不知道怎麼解釋這個問題。也希望大神能夠指出,感激不盡

protected function initialize()

parent::initialize(); // todo: change the autogenerated stub

$this->name('order_1');//將table方法換位name方法

name方法是也是指定表名,只是不帶表字首。經測試,傳入不含表字首的表名可行,我這裡的資料表設計的時候沒有表字首,所以傳的都一樣。

那麼改過之後,再來列印下之前的sql

image.png

經測試可以正常切換兩個表~

本次部落格只在記錄,內容中有很多自己瞎猜的,站不住腳,讓大神見笑。非常希望能有大神指點

TP5提示模板不存在

解決方法 this fetch 控制器名 模板檔名 不能只寫成 this fetch 模板檔名 mkdir permission denied 跟檔案的許可權有關係,特別是自動生成的檔案或者目錄類的許可權,linux伺服器出於安全因素對於使用者的許可權有著嚴格的控制。所以解決mkdir premis...

tp5 模型關聯

二 文章中用到的表結構 image 表,儲存的位置資訊 banner 推薦位表,儲存推薦位的型別 banner item 表,推薦位中的資訊條目,可以看到它擁有外來鍵 img id theme 表,商品活動主題,包含頭圖,主題圖 product 表,商品表 theme product 表,theme...

TP5常量參考

ext 類庫檔案字尾 php think version 框架版本號ds 當前系統的目錄分隔符 think path 框架系統目錄 root path 框架應用根目錄 lib path 系統類庫目錄 預設為 think path.library core path 系統核心類庫目錄 預設為 lib ...