meius/laravel-filter
Composer 安装命令:
composer require meius/laravel-filter
包简介
A Laravel package for applying dynamic filters to Eloquent models based on request parameters.
README 文档
README
Table of Contents
- Overview
- Requirements
- Getting Started
- Installation
- Configuration
- Usage
- Configuring Filter Aliases and Prefixes
- Examples for Other Databases
- Support
- License
Overview
The meius/laravel-filter package provides a convenient way to apply filters to Eloquent models in a Laravel application. It allows you to define filters using attributes and apply them dynamically based on the request.
Requirements
- PHP >= 8.0
- Laravel >= 9.0
Getting Started
To get started with the meius/laravel-filter package, follow the installation instructions below and check out the usage examples.
Installation
- Install the package via Composer:
composer require meius/laravel-filter
Configuration
- To publish the configuration file, run the following command:
php artisan vendor:publish --tag=filter-config
This will create a config/filter.php file where you can customize the filter settings.
Usage
Creating Filters
- To create a new filter, use the
make:filterArtisan command:php artisan make:filter {name}
Applying Filters
-
Define filters using attributes in your controller methods:
use App\Attributes\Filter\ApplyFiltersTo; use App\Models\Post; class PostController { #[ApplyFiltersTo(Post::class)] public function index() { return Post::query()->get(); } }
-
To apply filters to related models, use the
ApplyFiltersToattribute with multiple model classes:use App\Attributes\Filter\ApplyFiltersTo; use App\Models\Author; use App\Models\Comment; use App\Models\Post; class PostController { #[ApplyFiltersTo(Post::class, Comment::class, Author::class)] public function index() { return Post::query() ->with([ 'comments', 'author', ]) ->get(); } }
Applying Filters to Route Groups
By default, filters are applied to the web and API route groups. To customize this behavior, you must publish the configuration file and make the necessary adjustments.
-
Publish the Configuration File:
php artisan vendor:publish --tag=filter-config
-
Update the Configuration: Open the
config/filter.phpfile and modify theroute_groupssection to specify which groups should have filters applied.return [ // Filters will not be applied to API route groups with this change. 'route_groups' => [ //'api', 'web', ], ];
Caching Filters
- To cache the filters for faster loading, run the following Artisan command:
php artisan filter:cache
Example
Here is an example of how to define and apply filters:
-
Create a filter:
use Illuminate\Database\Eloquent\Builder; use Meius\LaravelFilter\Filters\Filter; class TitleFilter extends Filter { /** * The key used to identify the filter parameter in the request. */ protected string $key = 'title'; protected function query(Builder $builder, $value): Builder { return $builder->where('title', 'like', "%$value%"); } }
-
Create a filter for related models:
use Illuminate\Database\Eloquent\Builder; use Meius\LaravelFilter\Filters\Filter; class AuthorIdFilter extends Filter { protected string $key = 'author_id'; protected function query(Builder $builder, $value): Builder { return $builder->whereHas('author', function (Builder $query) use ($value): void { $query->where('id', '=', $value); }); } }
-
If you need to apply a filter according to a condition, you can use the
canContinuemethod:use Illuminate\Database\Eloquent\Builder; use Meius\LaravelFilter\Filters\Filter; class OwnerFilter extends Filter { protected string $key = 'owner'; protected function query(Builder $builder, $value): Builder { return $builder->where('user_id', '=', $value); } protected function canContinue(Request $request): bool { return $request->user()->hasSubscription(); } };
Using ExcludeFrom and OnlyFor Attributes
You can use the ExcludeFrom and OnlyFor attributes to conditionally apply filters.
-
Create a filter with
ExcludeFrom:use App\Models\User; use App\Models\Category; use Meius\LaravelFilter\Attributes\ExcludeFrom; use Meius\LaravelFilter\Filters\Filter; // The filter will never be applied to the "User" model and beyond. #[ExcludeFrom(User::class, Category::class, ...)] class ContentFilter extends Filter { protected string $key = 'content'; protected function query(Builder $builder, $value): Builder { // Filter logic } }
-
Create a filter with
OnlyFor:use App\Models\Post; use App\Models\Comment; use Meius\LaravelFilter\Attributes\OnlyFor; use Meius\LaravelFilter\Filters\Filter; // The filter will be applied to the "Post" model and beyond only. #[OnlyFor(Post::class, Comment::class, ...)] class ContentFilter extends Filter { protected string $key = 'content'; protected function query(Builder $builder, $value): Builder { // Filter logic } }
-
You can also use the
ExcludeFromandOnlyForattributes together(If you need it \@_@/):use App\Models\Comment; use App\Models\Post; use App\Models\User; use Meius\LaravelFilter\Attributes\ExcludeFrom; use Meius\LaravelFilter\Attributes\OnlyFor; use Meius\LaravelFilter\Filters\Filter; // The filter will be applied to the "Comment" and "User" models only. #[ OnlyFor(Post::class, Comment::class, User::class), ExcludeFrom(Post::class), ] class ContentFilter extends Filter { protected string $key = 'content'; protected function query(Builder $builder, $value): Builder { // Filter logic } }
-
Create a filter using properties:
use App\Models\Comment; use App\Models\Post; use Meius\LaravelFilter\Filters\Filter; class ContentFilter extends Filter { /** * The models to which the filter should exclusively apply. * * @var array<Model> */ protected array $onlyFor = [ Comment::class, Post::class, ]; /** * The models to which the filter should not be applied. * * @var array<Model> */ protected array $excludeFrom = []; protected string $key = 'content'; protected function query(Builder $builder, $value): Builder { // Filter logic } }
-
Create a filter using methods:
use App\Models\Comment; use App\Models\Post; use Meius\LaravelFilter\Filters\Filter; class ContentFilter extends Filter { protected string $key = 'content'; protected function query(Builder $builder, $value): Builder { // Filter logic } protected function onlyFor(): array { return [ User::class, Category::class, ]; } protected function excludeFrom(): array { return []; } }
Prioritization of Settings
When defining filter settings, the priority of the settings is as follows:
- Method: The highest priority. If a method is defined to specify the filter settings, it will override any settings defined via properties or attributes.
- Property: Medium priority. If a property is defined to specify the filter settings, it will override any settings defined via attributes but will be overridden by method definitions.
- Attribute: The lowest priority. If settings are defined via attributes, they will be used only if there are no corresponding settings defined via methods or properties.
This means that if there are conflicting settings defined in multiple ways, only the setting with the highest priority will be applied. For example, if a filter has both a method and an attribute defining the same setting, the method's setting will take precedence and be applied, while the attribute's setting will be ignored.
Example Request Structure
-
For filters to work correctly, the query must have the appropriate structure. Here is an example of how the query should be structured:
{ "filter": { "posts": { "title": "Deep Thoughts on the Hitchhiker's Guide", "published_after": "2005-04-28" }, "comments": { "content": "The answer to this question is 42" } } } -
Example request:
GET /posts?filter[posts][title]=Hitchhiker&filter[posts][published_after]=2005-04-28&filter[comments][content]=42
Configuring Filter Aliases and Prefixes
Adding Filter Aliases to Models
-
To add filter aliases to your models, use the
HasFilterAliastrait and define the$filterAliasproperty in your model.namespace App\Models; use Illuminate\Database\Eloquent\Model; use Meius\LaravelFilter\Traits\HasFilterAlias; class HtmlFivePackage extends Model { use HasFilterAlias; protected string $filterAlias = 'h5p'; }
Configuring the Filter Prefix
-
You can change the filter prefix by modifying the
config/filter.phpconfiguration file. Update theprefixvalue to your desired string.return [ 'prefix' => 'f', ];
Example JSON and URL Requests
-
JSON Request
Here,
"f"is the filter prefix specified in the config, and"h5p"is the alias defined in the model.{ "f": { "h5p": { "name": "blog" } } } -
URL Request
Similarly, in the URL request,
"f"represents the filter prefix and"h5p"is the alias.GET /posts?f[h5p][name]=blog
Advanced Usage
Complex Filters
- Create a complex filter that combines multiple conditions:
use Illuminate\Database\Eloquent\Builder; use Meius\LaravelFilter\Filters\Filter; class ComplexFilter extends Filter { protected string $key = 'complex_filter'; protected function query(Builder $builder, $value): Builder { return $builder->where('status', 'active') ->where(function ($query) use ($value) { $query->where('name', 'like', "%{$value}%") ->orWhere('description', 'like', "%{$value}%"); }); } }
Combined Filters
- Apply multiple filters to a single query:
use Illuminate\Database\Eloquent\Builder; use Meius\LaravelFilter\Filters\Filter; class CombinedFilter extends Filter { protected string $key = 'combined_filter'; protected function query(Builder $builder, $value): Builder { return $builder->where('category', $value['category']) ->where('price', '>=', $value['min_price']) ->where('price', '<=', $value['max_price']); } }
Examples for Other Databases
Using the query method, you can create filters for different databases.
PostgreSQL
- Create a filter for a PostgreSQL database:
use Illuminate\Database\Eloquent\Builder; use Meius\LaravelFilter\Filters\Filter; class TitleFilter extends Filter { protected string $key = 'title'; protected function query(Builder $builder, $value): Builder { return $builder->whereRaw('title ILIKE ?', ["%{$value}%"]); } }
SQLite
- Create a filter for an SQLite database:
use Illuminate\Database\Eloquent\Builder; use Meius\LaravelFilter\Filters\Filter; class TitleFilter extends Filter { protected string $key = 'title'; protected function query(Builder $builder, $value): Builder { return $builder->where('title', 'like', "%{$value}%"); } }
Support
For support, please open an issue on the GitHub repository.
Contributing
We welcome contributions to the meius/laravel-filter library. To contribute, follow these steps:
- Fork the Repository: Fork the repository on GitHub and clone it to your local machine.
- Create a Branch: Create a new branch for your feature or bugfix.
- Write Tests: Write tests to cover your changes.
- Run Tests: Ensure all tests pass by running
phpunit. - Submit a Pull Request: Submit a pull request with a clear description of your changes.
For more details, refer to the CONTRIBUTING.md file.
License
This package is open-sourced software licensed under the MIT license.
meius/laravel-filter 适用场景与选型建议
meius/laravel-filter 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 46 次下载、GitHub Stars 达 5, 最近一次更新时间为 2024 年 09 月 27 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「filter」 「model」 「dynamic」 「attributes」 「request」 「laravel」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 meius/laravel-filter 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 meius/laravel-filter 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 meius/laravel-filter 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Flexslider slideshow content block for Silverstripe Elemental
Nova searchable filter for belongsTo relationships.
A package for automatically encrypting and decrypting Eloquent attributes in Laravel 5.5+, based on configuration settings.
EAV modeling package for Eloquent and Laravel.
Write down your routing mapping at one place
Interfaces for web resource models and services to retrieve and create them
统计信息
- 总下载量: 46
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 5
- 点击次数: 9
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2024-09-27