在 symfony 7.1 中创建状态机,必须先安装并启用 workflow 组件,手动创建 config/packages/workflow.yaml 配置文件,定义 state_machine 类型及 places、transitions,为 order 实体添加 public string $state 字段并确保 doctrine 映射正确,最后通过 workflowregistry 获取状态机服务调用 can() 和 apply() 方法。

在 Symfony 7.1 中创建状态机,必须先确认项目已启用 Workflow 组件且配置文件结构符合新版本规范,否则会因组件未加载或 YAML 格式错误导致 【workflow.yaml 无法被识别】,后续所有操作都无效。
安装并启用 Workflow 组件
执行命令安装:composer require symfony/workflow
安装完成后,Symfony Flex 通常会自动注册 workflow.yaml 配置文件;若未生成,需手动在 config/packages/ 目录下创建 workflow.yaml 文件。
这一步不能跳过——即使你只打算用 PHP 数组定义状态机,Workflow 组件本身也必须启用,否则 Kernel 启动时会抛出 Class 'Workflow' not found 错误。
定义状态机配置(YAML 方式)
在 config/packages/workflow.yaml 中写入以下内容:
framework:
workflows:
order_processing:
type: 'state_machine'
marking_store:
type: 'single_state'
arguments: ['state']
supports: ['App\Entity\Order']
initial_place: 'created'
places:
- created
- pending_payment
- paid
- shipped
- completed
transitions:
confirm_order:
from: 'created'
to: 'pending_payment'
pay:
from: 'pending_payment'
to: 'paid'
注意:【places 必须是数组,且每个元素为纯字符串,不能带引号嵌套引号】,例如写成 '- "created"' 会导致解析失败,symfony/console 不报错但状态机不生效。
为实体添加状态字段
在 App\Entity\Order 类中,添加 public string $state = 'created'; 字段。
如果使用 Doctrine,确保该字段已映射为字符串类型,并在数据库迁移中同步该字段(如未同步,$state 值将始终为空,导致 apply() 报 “Transition does not exist”)。
这一步不可省略——Symfony 状态机不会自动创建或管理实体字段,它只读取和修改你声明的 $state 属性。
获取并使用状态机服务
在控制器或服务中注入 WorkflowRegistry:
use Symfony\Contracts\Service\Attribute\Required;
use Symfony\Component\Workflow\Registry;
public function __construct(private readonly Registry $workflowRegistry) {}
然后调用:
$order = new Order();
$workflow = $this->workflowRegistry->get($order);
if ($workflow->can($order, 'confirm_order')) {
$workflow->apply($order, 'confirm_order');
}
注意:不要直接 new Workflow() —— Symfony 7.1 中状态机实例由容器统一管理,手动实例化会导致监听器、持久化、守卫等扩展能力全部失效。











