Laravel 系列:orWhere 條件式

imxfly發表於2017-09-13

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 協議》,轉載必須註明作者和本文連結
公眾號:程式設計之謎

相關文章