TP5_模型初始化_踩坑記錄
前言:
先交代下背景,在一個專案中,有一個資料表有水平分表的需求。當時想找到一種方法,把對資料庫的操作,寫到一個模型裡,通過去換模型屬性中的table來達到程式碼不變操作的資料表變化的效果。
我們都知道,模型要想關聯資料表的話,有兩中方式,第一種就是將模型名和資料表一致。這樣模型就會預設關聯到名字對應的資料表。第二種就是定義模型的 protected $table 來指定表明。我當時就想,有沒有什麼方法,能初始化模型物件的時候將table屬性賦值呢,這個值存在資料庫裡。這樣就可以動態的來控制這個模型關聯的表名了。
模型初始化
基於以上的需求,文件裡的模型初始化引起了我的注意
我感覺這是我要找的東西。緊接著我著手開始測試
我根據手冊的寫法,在呼叫父類初始化後面,寫上對table的初始化,那麼現在我們來列印出來例項化的order模型
從圖中大家可以發現,table屬性的確已經修改了。然後我就沒有再做更多的測試了,因為我試過手動將table資料改為別的表名,就可以修改模型所關聯的資料表。我想這個table屬性已經有了肯定就沒問題了。
直到我在這個模型裡寫了很多方法後,我想去回來換個表名來試試寫入資料。爆炸的事情出現了。
//我使用包含table屬性的物件去查資料庫。查詢出來的結果,居然任然是原來那個模型名對應的表
$order = new \app\API\model\Order();
return $order->select();
這就很爆炸了,我已經寫好的這麼多程式碼難道都不能用了?
冷靜下來之後,我決定先試試,手動在模型中該表table屬性來試試。
那麼我們再來訪問下呢?
報錯,報表不存在,這是正確的,因為我沒有建立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方法中,看了下注釋
看樣子是我需要的方法,可這個方法不是模型基類裡的啊,是在query類當中的。我有些摸不清楚頭腦,但不管怎樣,還是要試一試
為了讓程式碼不報錯,我去增加了一個order_1表。這一試,嘿嘿,搞定了!
列印出了我在新表中的一條資料。哈哈,看來這個思路是可行的
就在我認為這個思路是可行的時候,我在執行我寫好的一些模型方法時,我發現了一個大坑!!
我就不詳細說我是怎麼發現的了。直接看程式碼
模型裡我還是這麼寫的
protected function initialize()
{
parent::initialize(); // TODO: Change the autogenerated stub
$this->table('order_1');//假裝這裡名字是從資料庫裡取得
}
//控制器裡例項化模型後,呼叫count方法
$order = new \app\API\model\Order();
var_dump($order->count());
var_dump($order->count());die;
結果讓人非常的震驚!
同一個物件,呼叫同一個方法,結果居然不一樣!我反覆試過都是這樣。我決定將他們的sql列印出來看看有什麼問題
結果同樣是讓人哭笑不得
結果模型初始化是一次性的?(黑人問號.jpg)
我當時就覺得是tp5的bug,我要向作者反應!
後來我冷靜下來,還是先把專案問題解決了來再說哦。飯碗要緊。
最終經過我的摸(luan)索(gao) ,我找到解決方案。下面就把程式碼貼出來,但是我確實不知道怎麼解釋這個問題。也希望大神能夠指出,感激不盡
protected function initialize()
{
parent::initialize(); // TODO: Change the autogenerated stub
$this->name('order_1');//將table方法換位name方法
}
name方法是也是指定表名,只是不帶表字首。經測試,傳入不含表字首的表名可行,我這裡的資料表設計的時候沒有表字首,所以傳的都一樣。
那麼改過之後,再來列印下之前的sql
經測試可以正常切換兩個表~
本次部落格只在記錄,內容中有很多自己瞎猜的,站不住腳,讓大神見笑。非常希望能有大神指點
相關文章
- ONNX模型轉Openvino部署踩坑記錄模型
- laravel踩坑記錄Laravel
- sealos踩坑記錄
- DietPi踩坑記錄
- strtotime 踩坑記錄
- ABP框架踩坑記錄框架
- Electron工程踩坑記錄
- gorm踩坑記錄(一)GoORM
- MySQL_踩坑記錄MySql
- Laravel7 踩坑記錄Laravel
- vuePC專案踩坑記錄Vue
- React專案踩坑記錄React
- node link 踩坑記錄
- ES6踩坑記錄
- Go json 踩坑記錄GoJSON
- Taro 小程式 踩坑記錄
- Mac下Charles踩坑記錄Mac
- 微信小程式踩坑記錄微信小程式
- React同構踩坑記錄React
- iOS11踩坑記錄iOS
- list複製踩坑記錄
- flutter前端入門踩坑記錄Flutter前端
- Electron Built-in AutoUpdater 踩坑記錄UI
- ijkplayer編譯踩坑記錄編譯
- uniapp開發踩坑記錄APP
- Next.js踩坑記錄JS
- 微信小程式BLE踩坑記錄微信小程式
- mybatis學習與踩坑記錄MyBatis
- 我的學習(踩坑)記錄
- laravel-echo-server 踩坑記錄LaravelServer
- 新手學習laravel踩坑記錄Laravel
- Laragon 編譯 Vue 踩坑記錄Go編譯Vue
- JavaScript兩數相加(踩坑)記錄JavaScript
- CocoaPods 整合 SnapKit 踩坑記錄APK
- Android Studio踩坑記錄Android
- 頁面初始化呼叫configuration.setLocale()介面踩坑記錄
- 記錄使用 guzzlehttp 異常捕獲踩坑記錄HTTP
- npm publish的釋出記錄(踩坑記)NPM