Eloquent 条件查询——tucker-eric/eloquentfilter 笔记
请阅读 https://github.com/Tucker-Eric/EloquentFilter , 里面有很全的文档和注释,以下仅列出关键部分。
1. 安装
composer require tucker-eric/eloquentfilter
2. 添加Provider
在 config/app.php 中添加 EloquentFilter\ServiceProvider::class
'providers' => [ // Other service providers... EloquentFilter\ServiceProvider::class, ],
3. 添加配置
php artisan vendor:publish --provider="EloquentFilter\ServiceProvider"
在 config 下出现 eloquentfilter.php 。
注意配置文件中 命名空间配置
'namespace' => "App\\ModelFilters\\",
默认会读取该命名空间下类,若使用其他命名空间类,需要修改该配置,或者传入该类 。
//使用默认命名空间
Post::filter(['title'=>'23'])->get();
//指定类
$userFilter = App\ModelFilters\User\UserFilter::class;
User::filter($input, $userFilter)->get();
,或者在Model 中指定(下面会提到)。
4. 修改Model
以User 为例
namespace App;
//必须引入 use EloquentFilter\Filterable; use Illuminate\Database\Eloquent\Model; class User extends Model {
//使用Trait , 其中有 scopeFilter, 以便可以静态调用, User::filter use Filterable;
//指定使用的过滤类 public function modelFilter() { return $this->provideFilter(App\ModelFilters\User\UserFilter::class); } //User Class }
5. 使用
5.1 动态过滤
namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use App\User; use App\ModelFilters\Admin\UserFilter as AdminFilter; use App\ModelFilters\User\UserFilter as BasicUserFilter;
// 若没有添加alias , 参考 github 上文档会找不到类 use Illuminate\Support\Facades\Auth; class UserController extends Controller { public function index(Request $request) { $userFilter = Auth::user()->isAdmin() ? AdminFilter::class : BasicUserFilter::class; return User::filter($request->all(), $userFilter)->get(); } }
文档中提高了很多功能和配置,这里不再复述,有不对的地方请指正!
补充:
1. User 表结构
CREATE TABLE `users` ( `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `remember_token` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL, `created_at` timestamp(0) NULL DEFAULT NULL, `updated_at` timestamp(0) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Compact;
2. Filterable 源码
trait Filterable { /** * Creates local scope to run the filter. * * @param $query * @param array $input * @param null|string|ModelFilter $filter * @return \Illuminate\Database\Eloquent\Builder */ public function scopeFilter($query, array $input = [], $filter = null) { // Resolve the current Model's filter if ($filter === null) { $filter = $this->getModelFilterClass(); } // Create the model filter instance $modelFilter = new $filter($query, $input); // Set the input that was used in the filter (this will exclude empty strings) $this->filtered = $modelFilter->input(); // Return the filter query return $modelFilter->handle(); } }
3. UserFilter 代码
use EloquentFilter\ModelFilter;
class UserFilter extends ModelFilter {
/**
* 关联查询中使用 * Related Models that have ModelFilters as well as the method on the ModelFilter * As [relationMethod => [input_key1, input_key2]]. * 具有ModelFilters的相关模型以及ModelFilter上的方法 如[relationMethod => [input_key1,input_key2]]。
* @var array */ public $relations = [];
// 黑名单
// 过滤器不会调用blackist数组中定义的任何方法。这些方法通常用于内部过滤器逻辑
protected $blacklist = ['secretMethod'];
/**
* 过滤是以表字段-方法,做了映射,
*/
// User 表中字段 email public function email($email) { return $this->where('email', '=', $email); } // User 表中字段 public function name($name) { return $this->where(function($q) use ($name) { return $q->where('name', 'LIKE', "%$name%"); }); } // User 表中字段名 public function phone($phone) { return $this->where('phone', 'LIKE', "%$phone%"); } //每次filter,都会调用,非必需(参考 ModelFilter->filter ) public function setup() { $this->onlyShowDeletedForAdmins();
//$this->xxx(); } public function onlyShowDeletedForAdmins() { if(Auth::user()->isAdmin()) { //$this->withTrashed(); } } // public function secretMethod($secretParameter) { return $this->where('some_column', true); }
4. 父类 EloquentFilter\ModelFilter
use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Database\Eloquent\Builder as QueryBuilder; /** * @mixin QueryBuilder */ abstract class ModelFilter { /** * ModelFilter constructor. * * @param $query * @param array $input * @param bool $relationsEnabled */ public function __construct($query, array $input = [], $relationsEnabled = true) { $this->query = $query; $this->input = $this->removeEmptyInput($input); $this->relationsEnabled = $relationsEnabled; $this->registerMacros(); } /** * @param $method * @param $args * @return mixed */ public function __call($method, $args) { $resp = call_user_func_array([$this->query, $method], $args); // Only return $this if query builder is returned // We don't want to make actions to the builder unreachable return $resp instanceof QueryBuilder ? $this : $resp; } /** * Handle all filters. * * @return QueryBuilder */ public function handle() { // Filter global methods if (method_exists($this, 'setup')) { $this->setup(); } // Run input filters $this->filterInput(); // Set up all the whereHas and joins constraints $this->filterRelations(); return $this->query; } }