Laravel Pipeline 是一个强大的设计模式实现,它允许通过定义一系列可重用的管道来优雅地处理数据。
通过 Pipeline 可以将复杂的数据处理逻辑拆分成小的、独立的步骤,使代码更具可维护性和可测试性。
要使用 Pipeline,可以创建 Illuminate\Pipeline\Pipeline
类的实例并定义管道和要处理的数据:
use Illuminate\Pipeline\Pipeline;
Pipeline::send($data)
->through($pipes)
->thenReturn();
示例一 处理评论
当需要处理用户评论时,可以使用Laravel 的 Str 类来处理评论中的敏感词,也可以使用 Pipeline 来处理评论中的敏感词。
use Closure;
use Illuminate\Support\Facades\Pipeline;
$comment = " Hey you :-) ";
Pipeline::send($comment)
->through([
function (string $comment, Closure $next) {
$comment = trim($comment);
return $next($comment);
},
function (string $comment, Closure $next) {
$comment = str_replace(':-)', '😊', $comment);
return $next($comment);
},
])
->thenReturn();
use Illuminate\Support\Str;
$comment = " Hey you :-) ";
Str::of($comment)->trim()->replace(':-)', '😊')->toString();
示例二 搜索
当需要根据名称、国家或角色搜索和排序时,有多种实现方式。
if 条件
使用 if 条件判断来完成类似的需求。
$usersQuery = User::query();
if ($request->has('name')) {
$usersQuery->where('name', 'like', "%{$request->get('name')}%");
}
if ($request->has('role')) {
$usersQuery->where('role', $request->get('role'));
}
if ($request->has('country')) {
$usersQuery->where('country', $request->get('country'));
}
$usersQuery->orderByDesc('id');
$usersQuery->paginate();
when 方法
使用 Eloquent 的 when
方法来完成类似的需求。
$usersQuery = User::query();
$usersQuery->when($request->has('name'), fn ($query) => $query->where('name', 'like', "%{$request->get('name')}%"));
$usersQuery->when($request->has('role'), fn ($query) => $query->where('role', $request->get('role')));
$usersQuery->when($request->has('country'), fn ($query) => $query->where('country', $request->get('country')));
$usersQuery->orderByDesc('id');
$usersQuery->paginate();
Pipeline
使用 Pipeline 来完成类似的需求,具体代码可以查看这个仓库:laravel-pipeline-demo。
use App\Filters\ByName;
use App\Filters\ByRole;
use App\Filters\ByCountry;
use App\Filters\SortUsers;
$pipes = [
new ByName($request->get('name')),
new ByRole($request->get('role')),
new ByCountry($request->get('country')),
SortUsers::class,
];
Pipeline::send(User::query())
->through($pipes)
->thenReturn()
->paginate();
<?php
namespace App\Filters;
use Closure;
use Illuminate\Database\Eloquent\Builder;
final class ByCountry
{
public function __construct(protected ?string $country)
{
//
}
public function handle(Builder $query, Closure $next)
{
return $next($query)->when(
$this->country,
fn ($query) => $query->where('country', $this->country)
);
}
}
<?php
namespace App\Filters;
use Closure;
use Illuminate\Database\Eloquent\Builder;
final class ByName
{
public function __construct(protected ?string $name)
{
//
}
public function handle(Builder $query, Closure $next)
{
return $next($query)->when(
$this->name,
fn (Builder $query) => $query->where('name', 'like', "%{$this->name}%")
);
}
}
<?php
namespace App\Filters;
use Closure;
use Illuminate\Database\Eloquent\Builder;
final class ByRole
{
public function __construct(protected ?string $role)
{
//
}
public function handle(Builder $query, Closure $next)
{
return $next($query)
->when(
$this->role,
fn ($query) => $query->where('role', $this->role)
);
}
}
<?php
namespace App\Filters;
use Closure;
use Illuminate\Database\Eloquent\Builder;
final class SortUsers
{
public function handle(Builder $query, Closure $next)
{
return $next($query)->orderByDesc('id');
}
}
每个管道都根据用户提供的条件应用特定的筛选或排序操作,最后返回经过过滤和排序的用户。
更多关于 Pipeline 的使用方法可以参考 Laravel Gems - Pipelines、在实际场景中使用 Laravel Pipeline:实际示例或Laravel Pipelines: Build an Api。