本文目录导读:

在PHP项目中实现流程部署(或称为工作流/审批流),通常有几种不同的技术路线,具体采用哪种,取决于你的项目规模、预算、以及对灵活性的要求。
下面我将从轻量级自实现、使用现有PHP工作流引擎、以及基于状态机三个方面来详细说明。
核心概念理解:流程的三要素
在实现之前,先明确流程的核心,无论用什么方法,都围绕这三个要素:
- 节点 (Node/Task):流程中的每一步,发起申请”、“经理审批”、“HR确认”。
- 连线/条件 (Transition/Condition):决定从一个节点到下一个节点的规则,如果同意,则去HR节点;如果驳回,则返回发起节点”。
- 实例 (Process Instance):某一次具体的流程运转,张三的请假流程实例”。
数据库硬编码 + 状态机(最常用、最可控)
这是绝大多数中小型PHP项目采用的方式,它不依赖外部引擎,性能高,逻辑清晰,但修改流程需要改代码。
核心思想:用数据库的一张或多张表记录流程状态,用PHP代码中的switch、match或状态模式控制流转。
实现步骤:
-
数据库设计(简化版):
leave_requests表:存储请假单数据,包含关键字段status(pending_dm,approved_dm,pending_hr,approved,rejected)。
-
代码逻辑(Controller层):
// 假设用户提交了审批操作(同意/驳回) public function handleApproval(Request $request) { $leaveRequest = LeaveRequest::find($request->leave_id); $action = $request->action; // 'approve' 或 'reject' $user = auth()->user(); if ($leaveRequest->status == 'pending_dm') { // 当前是主管审批阶段 if ($user->id != $leaveRequest->dm_id) { throw new \Exception('您不是当前审批人'); } if ($action == 'approve') { // 主管同意,流转到HR $leaveRequest->status = 'pending_hr'; $leaveRequest->dm_approved_at = now(); // 发送通知给HR:leaveRequest->hr_id } else { // 主管驳回,流程结束,状态变为已驳回 $leaveRequest->status = 'rejected'; $leaveRequest->rejected_reason = $request->reason; // 发送通知给申请人 } } elseif ($leaveRequest->status == 'pending_hr') { // 当前是HR审批阶段 // ... 类似逻辑 if ($action == 'approve') { $leaveRequest->status = 'approved'; // 流程结束 } else { $leaveRequest->status = 'rejected'; } } $leaveRequest->save(); return back()->with('success', '操作成功'); }
优点:
- 简单直接,性能极好。
- 完全可控,调试方便。
- 无需引入复杂第三方包。
缺点:
- 流程改动(增加一个副总审批节点)需要修改PHP代码和数据库字段。
- 分支条件多时,
if-else会变得臃肿。 - 不适用于需要用户动态配置流程的场景。
使用 PHP 工作流引擎(适合复杂、动态流程)
如果你的系统需要让非技术人员(如运营人员)在后台自由拖拽设计流程(OA系统、工单系统),则需要使用专业的工作流引擎。
在PHP领域,最成熟的选择是 Symfony Workflow 组件,它虽来自Symfony框架,但可独立用于任何PHP项目(Laravel、ThinkPHP等)。
安装与概念
composer require symfony/workflow
核心概念:
- 定义 (Definition):用代码(YAML/PHP数组)定义状态和流转。
- Place (地点/状态):相当于
pending_dm。 - Transition (流转/动作):相当于
approve或reject。 - Marking (标记):当前流程实例处于哪个
Place。
实现步骤(以Laravel为例)
-
配置流程:在
config/workflow.php中定义:return [ 'leave_process' => [ 'type' => 'state_machine', // 或 'workflow'(支持多状态) 'marking_store' => [ 'type' => 'method', 'property' => 'status', // 对应模型字段 ], 'supports' => [\App\Models\LeaveRequest::class], 'places' => [ 'draft', 'pending_dm', 'pending_hr', 'approved', 'rejected', ], 'transitions' => [ 'submit' => [ 'from' => 'draft', 'to' => 'pending_dm', ], 'dm_approve' => [ 'from' => 'pending_dm', 'to' => 'pending_hr', ], 'dm_reject' => [ 'from' => 'pending_dm', 'to' => 'rejected', ], 'hr_approve' => [ 'from' => 'pending_hr', 'to' => 'approved', ], // ... ], ], ]; -
模型使用:
use Symfony\Component\Workflow\StateMachine; class LeaveRequestController { public function approve(LeaveRequest $leaveRequest, StateMachine $leaveProcessStateMachine) { // 检查是否可以执行 'dm_approve' 这个Transition if (!$leaveProcessStateMachine->can($leaveRequest, 'dm_approve')) { throw new \Exception('不允许此操作'); } // 执行流转:自动将 $leaveRequest->status 从 'pending_dm' 改为 'pending_hr' $leaveProcessStateMachine->apply($leaveRequest, 'dm_approve'); // 模型自动保存,因为Laravel有事件监听 // 可以在这里发送通知 } } -
可视化 & 动态化:
- 开源工具 Petri Net 或 BPMN 解析器可以将流程定义渲染为图形。
- 如果需要完全UI化拖拽设计,PHP端很难完美实现(通常需要配合前端流程图库如
bpmn-js或mxGraph),原理是:前端拖拽 -> 将生成的JSON/XML保存到数据库 -> PHP解析这个定义文件 -> 动态构建Symfony Workflow Definition。
优点:
- 流程逻辑与业务代码解耦。
- 流程修改只需改配置文件或数据库记录,无需动PHP业务代码。
- Symfony组件经过严格测试,稳定可靠。
- 支持
Guard(守卫条件,如判断金额是否大于5000才走某条线)。
缺点:
- 学习曲线较高(需要理解状态机、事件、Guard)。
- 对于简单的一两步审批,过度设计。
- 调试不如直接写if-else直观。
基于 BPMN 2.0 的标准引擎(企业级)
PHP生态中,完全支持BPMN 2.0(业务流程模型和表示法,业务流程建模的标准)的成熟引擎几乎没有(Java有Activiti/Flowable,.NET有Workflow Core)。
PHP通常扮演“客户端”或“桥接”角色:
-
Zeebe (Camunda Cloud):一个高性能的微服务工作流引擎,PHP应用通过其REST API或gRPC启动流程、完成任务。
// 使用 Zeebe PHP Client $client = new Zeebe\Client('grpc://localhost:26500'); // 启动一个BPMN流程实例 $response = $client->createWorkflowInstance('leave-process', [ 'employeeId' => 123, 'days' => 3 ]); // 完成任务 $client->completeWorkflowTask($taskKey, [ 'approved' => true ]); -
iGrafx / Signavio:纯粹的建模和监控工具,PHP只提供API调用。
优点:
- 标准、强大、有可视化图表和仿真。
- 支持复杂网关(并行、包容、异或)。
缺点:
- 需要额外部署一个Java/Go服务(Zeebe是Go写的,但生态系统偏向Java)。
- 网络开销和运维复杂度显著增加。
- 对PHP团队来说,引入分布式系统可能“杀鸡用牛刀”。
总结与选型建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 简单审批流(1-3级,固定不变) | 数据库状态机 | 最快、最省事、无需依赖 |
| 中等复杂度(流程有多个分支,偶尔需调整) | Symfony Workflow | 解耦、可控、可配置 |
| 用户可拖拽设计流程(类OA系统) | 方法二 + 前端bpmn-js | 最接近无代码平台 |
| 需要与Java/.NET系统集成,或流程极其复杂(并行、子流程、循环) | Zeebe + BPMN | 标准、可靠、可水平扩展 |
最后一条实用建议: 对于绝大多数PHP项目(包括CMS、ERP、简单OA),不要一开始就追求“动态工作流”,99%的流程需求在初期是相对固定的,先用方法一快速实现,等到业务部门确实提出了“我要自己画流程图”的真实需求(且预算充足),再重构为方法二或三,过早抽象会让开发周期翻倍。
如果你的开发环境是 Laravel,推荐一个插件:laravel-workflow(第三方包,对Symfony Workflow做了Laravel风格的封装),可以省不少力气。