# laravel filter設計 https://learnku.com/articles/29100#545579 https://segmentfault.com/a/1190000018654280 (先看這篇 再往下看 這篇超重要) ## 講一下 newQuery() newQuery () 是 model 的继承的 Database/Eloquent/Model ## 範例 假设我们有一个图书的列表,想要进行筛选: 标题含有 "我们" 的 定价大于 30 元的 出版社是 "大地出版社" 的 按照 ID 进行倒序排列 基础的 QueryFilter,然后我们所有的 Filter 都继承这个类 基本都是abstract class ``` abstract class QueryFilter { protected $request; protected $builder; public function __construct(Request $request) { $this->request = $request; } public function apply(Builder $builder) { $this->builder = $builder; foreach ($this->filters() as $name => $value) { if (method_exists($this, $name)) { call_user_func_array([$this, $name], array_filter([$value])); } } return $this->builder; } public function filters() { return $this->request->all(); } } ``` **BookFilter** ``` class BookFilter extends QueryFilter { public function title($title) { return $this->builder->where('title', 'like', "%{$title}%"); } public function price($price) { return $this->builder->where('price', '>=', "%{$price}%"); } public function publisher($publisher) { return $this->builder->where('publisher', $publisher); } } ``` 在上面的代码中,我们可以通过 URL 的参数来进行动态查询。 books?title=我们 // 查找标题含有我们的图书 books?title=我们&price=25 // 查找标题含有我们并且价格大于25元的图书 **当然,如果我们只进行到这一步是没法进行查询的,因为我们还没有地方调用 QueryFilter 中的 apply 方法。有一个绝佳的地方可以进行调用,那就是模型中的 scope**。 **注意:scopeFilter($query, QueryFilter $filters) 传参是抽象类,并使用该类调用了方法,所以实际使用时要传递实例化的继承类。** ``` class Book extends Model { public function scopeFilter($query, QueryFilter $filters) { return $filters->apply($query); } } ``` controller ``` public function index(BookFilter $filters) { return Book::filter($filters)->get(); } ``` ## 分頁面 ``` public function getModels($columns = ['*'], $request = null, $paginate = null, $with = null) { $query = $this->makeModelsQuery($request); return $this->getModelsByQuery($query, $columns, $paginate, $with); } ``` 第二個的 ``` /** * Get result model by query builder and with relations and paginate. * * @param Builder $query * @param array $columns * @param int|null $x * @param mixed|null $with */ public function getModelsByQuery($query, $columns = ['*'], $paginate = null, $with = null) { if ($with) { $query = $query->with($with); } if ($paginate) { return $query->paginate((int)$paginate, $columns); } return $query->get($columns); } ``` ###### tags: `Laravel`