Laravel,一個優雅的 PHP 框架,也是目前最火的 PHP 專案,其生態積極健康,社群也很活躍。:sparkling_heart:
目前我對於學習 Laravel 還是有些吃力的,基本方法都能很快掌握,但是一旦遇到了比較複雜的問題後,想要去檢視原始碼進行除錯的時候,總是會顯得不知所措。:dizzy_face: :dizzy_face: :dizzy_face: 官方文件不會把所有方法都講一遍,也不會把方法的各個使用場景都描述一遍,所以遇到這些問題去看文件一般解決不了。
改正一下,針對我下面這個問題,其實文件中有,是自己沒有看仔細,不好意思啦:傳送門
這次我遇到的問題是 orWhere
條件式造成的查詢語句寫法始終不是自己想要的。
場景描述
我需要根據商品分類、商品名稱和條形碼這三個查詢條件去取出結果集,這三者的關係是:商品分類 and (商品名稱 or 條形碼)
錯誤嘗試
第一次寫出來的程式碼是這樣的:
$goodsModel = new Goods;
if (!empty($category)) {
$goodsModel = $goodsModel->where('category', $category);
}
if (!empty($keyword)) {
$goodsModel = $goodsModel->where('name', 'like', "%{$keyword}%")->orWhere('barcode', 'like', "%{$keyword}%");
}
$goodsList = $goodsModel->limit(10)->get();
然後會發現這樣的寫法會導致三者的關係變成了:商品分類 and 商品名稱 or 條形碼。:shit: :shit: :shit:
谷歌一下
也是找了一會才找到,如果需要將 or 兩邊的查詢項作為一組查詢條件,那麼建議使用 where 的閉包方式。
閉包
這種方式將 or 部分寫成 closure 傳入 where()
,與 Eloquent 風格一致,可讀性較好。程式碼如下:
if (!empty($keyword)) {
$goodsModel = $goodsModel->where(function ($query) use ($keyword) {
$query->where('name', 'like', "%{$keyword}%")->orWhere('barcode', 'like', "%{$keyword}%");
});
}
原生
實在想不出怎麼寫,就寫原生 SQL 好了。這也是最後一種保險但不提倡的做法了吧,程式碼如下:
if (!empty($keyword)) {
$keyword = "%{$keyword}%";
$goodsModel = $goodsModel->whereRaw('(name like ? or barcode like ?)', [$keyword, $keyword]);
}
需要注意的是,單引號裡面的括號是不能省略的,否則一樣會導致這三者的關係是:商品分類 and 商品名稱 or 條形碼。
佔位符
再友情提示一下,你可能會對 like ?
覺得奇怪,我第一次寫的時候直接是 whereRaw('name like "%?%"', [$keyword]')
,但是這樣是沒效果的,原因是佔位符是對某一個完整的值進行佔位,而不是簡單的替換效果,所以需要將 like
的引數全部用 ?
替代,將百分號的拼接放在後面的佔位陣列的變數中去。:hear_no_evil: :hear_no_evil: :hear_no_evil:
參考連結:How do you parameterize whereRaw() in the query builder?
總結
一門技術,一個框架,想要精通,需要學的和看的有很多很多呢。。。:triumph: :triumph: :triumph:
本作品採用《CC 協議》,轉載必須註明作者和本文連結