問題描述
典型的手機號問題,數據庫varchar, 手機號加了索引,但是php傳參傳intpublic function getByPhone($phone){
return $this->userFollow
->where('phone', $phone)
->get();
}$this->getByPhone(13845678889); //不走索引打印出的原生sql是:string(48) "select * from zp_user_follow where phone = ?" array(1) { [0]=> int(15000475201) }
$this->getByPhone('13845678889'); //走索引打印出的原生sql是:string(48) "select * from zp_user_follow where phone = ?" array(1) { [0]=> string(11) "15000475201" }
問題出現的環境背景及自己嘗試過哪些方法
在變量前面加入類型public function getByPhone(string $phone){
return $this->userFollow
->where('phone', $phone)
->get();
}這是方式是強制約束,但是程序員如果不寫呢?如果傳的是個數組,數組里是['phone' => 13845678889];怎么解決?
相關代碼
laravel 底層是pdo,pdo綁定參數的底層代碼,是會判斷第三個參數使用的類型public function bindValues($statement, $bindings){
foreach ($bindings as $key => $value) {
$statement->bindValue(
is_string($key) ? $key : $key + 1, $value,
is_int($value) || is_float($value) ? PDO::PARAM_INT : PDO::PARAM_STR
);
}
}
你期待的結果是什么?實際看到的錯誤信息又是什么?
有沒有辦法,在不改底層laravel,就算程序員寫錯了,可以在查詢的時候,自動解析查詢參數的類型和數據庫字段類型進行匹配,也能正確保證走索引,如果沒有辦法,只能把問題拋給程序員?讓他們注意寫代碼的時候,聲明查詢參數的類型要和數據庫一致?如果他們忘記了怎么辦?問題在放大一點,假如生成環境數據量大,不走索引,全表掃描,如果因為這個問題,導致了慢sql,生成環境出bug, 扣績效?批評?
是把問題拋給人本身,如果拋給人本身,那么是我們習慣約定大于配置,給自己找個不想用技術手段解決的理由?還是可以用技術手段解決,就得改底層了,但是laravel底層為什么這么實現呢?它本身就把問題拋給我們開發者,需要我們執行約定?,希望有人解惑啊?。?!
3 回答

收到一只叮咚
TA貢獻1821條經驗 獲得超5個贊
這個和laravel沒有關系。
數據庫里的phone字段是varchar型,但是你查詢的數據是int型,這里導致了mysql隱式類型轉換,所以你的索引失效。
在設計表的時候就需要考慮好這些問題,實現的過程做好類型約束

手掌心
TA貢獻1942條經驗 獲得超3個贊
對!這就是程序員要處理的事情。
這種用法是PDO的方式,與laravel無關。
mysql的類型是開發者定義的,所以該使用什么類型,也由開發者決定
這是不是框架層和語言層要解決的事情,即使裸寫sql,一樣會有人寫錯。
換個角度,這其實是sql的使用知識,只不過通過中間層控制sql,有不同的使用規則,這是需要使用者掌握的
- 3 回答
- 0 關注
- 413 瀏覽
添加回答
舉報
0/150
提交
取消