Laravel如何利用Pipeline实现过滤器模式?(代码优雅)

尼克

尼克

2026-04-16

415人浏览

原创

pipeline 不是链式调用语法糖,因其核心价值在于责任分离与运行时动态组装,每个处理器只专注单一职责(如校验、脱敏),且 then() 返回最后一步结果,支持中途终止、类型可变、需显式实现 __invoke($passable, $next)。

laravel如何利用pipeline实现过滤器模式?(代码优雅)

为什么 Pipeline 不是「链式调用」的语法糖?

因为它的核心价值不在写法简洁,而在责任分离和运行时动态组装。你传给 send() 的值会依次被每个闭包或类处理器处理,且每个处理器只关心自己那一步的逻辑——比如权限校验、参数标准化、数据脱敏。如果把它当 collect()->map()->filter() 那样用,就浪费了它的中间件式控制流能力。

常见错误现象:Class App\Pipes\ValidatePipe does not exist,本质是没注册自动加载,或用了匿名函数却忘了在 pipe() 里显式传入实例。

  • 必须确保每个 pipe 是可调用的:类需实现 __invoke(),或直接传闭包
  • 类 pipe 推荐用完整命名空间路径字符串(如 'App\Pipes\TrimPipe'),Laravel 会自动 resolve
  • 闭包 pipe 要注意变量作用域,use ($request) 很容易漏掉引用

then() 返回值怎么接?别默认它返回原始输入

很多人以为 Pipeline 只是“过一遍”,最后一定拿到最开始传进来的那个 $request$data。其实每个 pipe 的返回值都会作为下一个 pipe 的输入,then() 的结果就是最后一个 pipe 的返回值——它可能是个布尔值、数组、模型实例,甚至 null。

使用场景:做 API 请求预处理时,你可能希望最终得到一个已验证并转换好的 OrderRequestDTO 对象,而不是原始 Request

Laravel 13.2.0
Laravel 13.2.0

PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。

下载
  • 如果某个 pipe 返回 false 或抛出异常,后续 pipe 不再执行(除非你手动 catch)
  • 想中途终止并返回特定结构,直接 return response()->json(...) 即可,但要注意这会让类型变得不可预测
  • 调试时加个日志 pipe:function ($passable) { \Log::debug('pipeline input:', ['value' => $passable]); return $passable; }

Laravel 10+ 的 Illuminate\Pipeline\Pipeline 默认不支持数组参数

如果你习惯把多个参数塞进数组传给 send(),比如 send(['user' => $user, 'post' => $post]),然后在 pipe 里期望解构,会发现所有 pipe 收到的都是这个数组——但 Laravel 的 pipeline 没有内置解包逻辑,它只认单个“通行物”(passable)。

性能影响:强行在每个 pipe 里 extract($passable)array_merge(...) 会增加开销,也破坏语义清晰性。

  • 正确做法是封装成对象(如 class PostPublishContext),让类型和意图明确
  • 如果坚持用数组,统一在第一个 pipe 里解构并返回新对象,后面 pipe 就不再面对数组
  • 别在 then() 后面链式调用 ->toArray() 之类方法——它不是 Collection

自定义 pipe 类必须实现 __invoke(),且参数签名不能错

这是最容易卡住的地方:Laravel 在 resolve pipe 类后,会以 $pipe($passable, $next) 方式调用,所以 __invoke() 必须接收两个参数,且第二个必须是 Closure 类型的 $next。少一个参数、类型不对、或者写了 public function handle() 却没配 handles 属性,都会导致 Too few arguments 错误。

示例正确写法:

class AuthCheckPipe
{
    public function __invoke($passable, Closure $next)
    {
        if (! $passable->user()->can('publish', $passable->post)) {
            throw new AuthorizationException();
        }

        return $next($passable);
    }
}
  • 不要试图在 __invoke() 里做耗时操作(如 DB 查询)却不加缓存,pipe 是同步阻塞执行的
  • 如果需要依赖注入,Laravel 会自动注入,但仅限构造函数;__invoke() 参数只能是 $passable$next
  • 测试时别 mock 整个 pipeline,而是单独测每个 pipe 的行为——它们本该是纯逻辑单元
事情说清了就结束

相关专题

更多
laravel组件介绍
laravel组件介绍

laravel 提供了丰富的组件,包括身份验证、模板引擎、缓存、命令行工具、数据库交互、对象关系映射器、事件处理、文件操作、电子邮件发送、队列管理和数据验证。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

2024.04.09

672

10

laravel中间件介绍
laravel中间件介绍

laravel 中间件分为五种类型:全局、路由、组、终止和自定。想了解更多laravel中间件的相关内容,可以阅读本专题下面的文章。

2024.04.09

627

9

laravel使用的设计模式有哪些
laravel使用的设计模式有哪些

laravel使用的设计模式有:1、单例模式;2、工厂方法模式;3、建造者模式;4、适配器模式;5、装饰器模式;6、策略模式;7、观察者模式。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

2024.04.09

1111

10

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.10

1547

7

laravel入门教程
laravel入门教程

本专题整合了laravel入门教程,想了解更多详细内容,请阅读专题下面的文章。

2025.08.05

1899

22

laravel实战教程
laravel实战教程

本专题整合了laravel实战教程,阅读专题下面的文章了解更多详细内容。

2025.08.05

1223

13

laravel面试题
laravel面试题

本专题整合了laravel面试题相关内容,阅读专题下面的文章了解更多详细内容。

2025.08.05

2693

7

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

2026.03.04

1087

29

Laravel 框架安装指南
Laravel 框架安装指南

本指南详解 Laravel 框架安装全流程,涵盖 PHP 8.1+ 环境配置、Composer 依赖管理工具安装及国内镜像源优化。重点演示使用 composer create-project 命令创建 Laravel 10/11 项目,解决常见安装错误与依赖冲突。从环境搭建到项目初始化,助您快速完成 Laravel 开发环境部署,为后续 Web 应用开发奠定基础。适合 PHP 初学者与框架迁移开发者参考。

2026.04.09

91

6

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
如何安装 Composer
如何安装 Composer

共1课时 | 128人学习

Composer手册
Composer手册

共0课时 | 0人学习