railgun1v9/lara-spf

此包已被废弃,不再维护。未建议替代包。

用于Laravel构建器和集合的排序、分页和筛选,利用URI的查询参数。

安装: 1

依赖者: 0

建议者: 0

安全性: 0

星星: 2

关注者: 0

分支: 0

开放问题: 0

类型:package

dev-master 2019-05-30 20:16 UTC

This package is auto-updated.

Last update: 2022-03-01 00:29:46 UTC


README

Latest Stable Version Total Downloads Latest Unstable Version License

用于Laravel构建器和集合的排序、分页和筛选,利用URI的查询参数。

致谢

此包使用了以下功能的实现:

johannesschobel/dingoquerymapper - 排序和分页功能

CamiloManrique/laravel-filter - 筛选功能

这两个库都有满足我需求的功能,但在安全性和其他需求方面有所不足。通过一点编辑和组合,我创建了一个集排序、分页和筛选于一体的解决方案。

安装

使用Composer安装包

composer require railgun1v9/lara-spf

railgun1v9\LaraSPF添加到config/app.php中的服务提供者

'providers' => [
    railgun1v9\LaraSPF\FilterServiceProvider::class
]

您可以将配置文件发布以更改默认设置

php artisan vendor:publish

从URI与LaraSPF交互

排序

默认情况下,LaraSPF按id以升序排序结果。以下是一个示例查询参数来执行此操作。

/customer?sort=id

要按不同的列和降序排序,可以在字段前加上减号。

/customer?sort=-name

分页

默认情况下,LaraSPF每页限制为15个结果。但您可以通过URI中的limit参数更改限制。

/customer?sort=id&limit=25

要转到结果的下一页,请附加一个page参数,其值为您想要查看的页码。

/customer?sort=id&limit=25&page=2

筛选

您可以根据以下示例通过键和值筛选结果。

/customer?name=BOB&sort=id&limit=25 注意,此筛选是大小写敏感的。

但是,您可以通过在您要筛选的键后附加/like来执行不区分大小写的搜索。

/customer?nam/like=bOb&sort=id&limit=25

使用

使用LaraSPF与集合

此包向Collection类添加了两个宏方法,增加了筛选和分页功能

$customers->filter($request)->paginate($request);

paginate方法可以与filter方法一起使用,为集合提供排序、分页和筛选功能。

使用LaraSPF与构建器

此包向Builder类添加了两个宏方法,允许在不进行任何其他设置的情况下使用筛选方法。这两个方法都可以接收一个HttpRequest、一个Collection或一个数组作为参数。下面将解释这两个方法。

方法名称注意事项: 宏方法名称可以在配置文件中进行自定义,以防Builder类宏中出现命名冲突。示例中将使用默认名称。

获取查询构建器实例

User::filter($request)

使用此方法,您可以获取一个查询构建器实例,在其中可以持续应用查询构建器方法,包括get()first()paginate()等。

获取模型实例

User::filterandGet($request)

此方法为您处理查询构建和获取。它甚至可以开箱即用地处理分页。默认情况下,使用此方法自动分页是开启的,但您可以通过发布配置文件并编辑它来更改此行为。

这些方法也可以不带参数调用,在这种情况下,查询不会应用任何过滤。

由于这些方法是Builder类的宏,因此在使用模型实例上的相关模型时也可以链式调用。例如,假设模型User与Post模型有关联,您可以使用它如下

$user = User::find(1)
$user->posts()->filterAndGet($request);

实际使用示例

从路由返回

Route::get('/users', function(){
    return User::filterAndGet(request());
});

从控制器返回

public function index(Request $request){
    return User::filterAndGet($request);
}

关于Eloquent API资源的说明:如果您正在使用Laravel 5.5,您也可以使用此包与Eloquent Resources的新功能一起使用。

Route::get('/users', function(){
    return UserResource::collection(User::filterAndGet(request()));
});

过滤规则

现在,这是一个重要的部分。我们已解释了如何安装和调用过滤方法,但您如何实际定义您的过滤器呢?对于基本查询来说很简单,如果您需要基于相关模型进行查询,那么会稍微复杂一些。

定义过滤列

在您的请求中,您只需将列名称用作键,将比较值用作值。

示例

假设您的应用程序URL为http://www.example.com,并且您定义了一个路由/users,该路由指向一个名为filter的控制器方法,如下所示

    namespace App\Http\Controllers;
    
    use App\Users;
    
    class UsersController extends Controller
    {
        public function filter(Request $request)
        {
            return User::filterAndGet($request);
        }
    }

假设您想要检索来自德国的用户。您的HTTP请求对象应该有一个名为country的键,其值设为德国。URI请求如下所示

    http://www.example.com/users?country=Germany

现在假设您想要更具体一些,并且您想要检索不仅是来自德国,而且是男性的用户。您的URI将变为如下所示

    http://www.example.com/users?country=Germany&gender=Male

请记住,您也可以使用集合和数组来传递所需的过滤器。以下示例使用数组作为参数的等效形式

    $filters = ["country" => "Germany", "gender" => "Male"]
    User::filterAndGet($filters);

查询比较运算符

上述示例仅适用于精确匹配,但您可能需要一个更宽松的比较,如>、<、LIKE和!=运算符提供的那种。为了使用这些运算符,您需要在列名称末尾附加一个关键字,并用斜杠字符分隔。此分隔字符可以在配置文件中更改。

以下是关键字及其对应运算符的列表

  • start: >= value
  • end: <= value
  • like: LIKE %value%
  • not: != value

示例

检索来自德国且年龄小于30岁的用户

    http://www.example.com/users?country=Germany&age%2Fend=30

在先前的示例中,%2F是斜杠字符的编码。

使用数组作为参数的等效形式

    $filters = ["country" => "Germany", "age/end" => 30]
    User::filterAndGet($filters);

高级使用

将相关模型添加到响应中

有时您可能需要从查询中检索额外的相关模型。您可以通过在输入中添加关键字"relationships"并将其值设置为要包含的关联(如模型类中定义,而非表名)的逗号分隔列表来实现。

如果您的模型中有一个名为"relationships"的列,则过滤器将表现异常。在这种情况下,请在配置文件中更改搜索关系键的数组中的关键词,并将其值更改为任何不会与您的列名冲突的词。

例如,假设您有一个包含两个相关模型(帖子(Posts)和评论(Comments))的用户模型,这些模型之间有一个一对多关系(一个用户可以有多个帖子)。现在,您只想获取来自德国的用户,但您想将用户的帖子评论包含在响应中。输入将如下所示

    $filters = ["country" => "Germany", "relationships" => "posts,comments"]
    User::filterAndGet($filters);

这样,每个用户的帖子(Posts)和评论(Comments)模型都将包含在响应中。

当加载具有许多模型的关联时请小心,因为它们都会被加载,这可能会导致非常慢的响应时间。

基于相关模型进行过滤

就像您可以在结果中包含相关模型一样,您也可以根据相关模型过滤结果。您只需在列名前加上关系和"@"字符。例如,假设一个用户模型有一个名为"account_info"的一对一关系,对应一个名为AccountInfo的模型,并且这个模型有一个名为"name"的属性。为了基于AccountInfo模型中的"name"列对用户模型进行过滤,输入将是

    $filters = ["account_info@name" => "John"]
    User::filterAndGet($filters);

获取求和聚合

有时,您不需要查询的实际模型。相反,您可能需要获取一个或多个属性的总和。在这种情况下,您应在输入中添加关键字"sum",并将其值设置为要获取总和的列或列(列应逗号分隔)。例如,获取某些用户帖子的总投票数

    $filters = ["user_id" => 1, sum" => "votes"]
    User::filterAndGet($filters);

另一个选项是使用Eloquent关系方法

    $user = User::find(1)
    $filters = ["sum" => "votes"]
    $user->posts()->filterAndGet($filters);