Shopware 6.5.3.3插件重构:全事件订阅者获取Session的替代方案咨询
在Shopware 6.5.3.3事件订阅者中统一获取Session的解决方案
问题根源
Shopware 6.5移除旧Session服务后,像CheckoutOrderPlacedEvent这类事件不一定在HTTP请求上下文中触发(比如可能通过消息队列异步执行),此时直接从Request对象获取Session自然无效。需要根据事件类型的差异,采用对应的获取逻辑。
具体解决办法
1. 针对HTTP请求上下文内的事件
对于CheckoutConfirmPageLoadedEvent这类在用户请求生命周期内触发的事件,继续使用原有方式即可:
$session = $event->getRequest()->getSession();
2. 关联订单/客户的事件(如CheckoutOrderPlacedEvent)
这类事件本身携带Order对象,可以通过订单关联的实体或预存数据替代Session的作用:
- 若Session中存储的是临时业务数据,可在请求阶段将其存入
SalesChannelContext或订单的自定义字段中 - 通过订单关联的客户ID查询客户信息,替代部分Session的用途
- 处理
CheckoutOrderPlacedEvent的示例代码:
public function onOrderPlaced(CheckoutOrderPlacedEvent $event): void { $order = $event->getOrder(); $customerId = $order->getCustomerId(); // 查询关联客户信息 $customer = $this->customerRepository->search(new Criteria([$customerId]), $event->getContext())->first(); // 读取预存在订单自定义字段中的Session临时数据 $customFields = $order->getCustomFields(); $tempSessionData = $customFields['your_temp_session_key'] ?? null; }
3. 使用新版SalesChannelSessionService
Shopware 6.5保留了Shopware\Core\System\SalesChannel\SalesChannelSessionService,通过依赖注入该服务,结合SalesChannelContext即可获取Session:
use Shopware\Core\System\SalesChannel\SalesChannelSessionService; class YourEventSubscriber { public function __construct(private readonly SalesChannelSessionService $sessionService) {} public function handleTargetEvent(YourTargetEvent $event): void { $salesChannelContext = $event->getSalesChannelContext(); $session = $this->sessionService->getSession($salesChannelContext); // 读取Session数据 $targetValue = $session->get('your_session_key'); } }
注意:该方法仅适用于能获取到SalesChannelContext的事件,大部分前端触发的业务事件都会携带此上下文。
4. 异步事件的特殊处理
如果事件通过消息队列异步执行,此时无HTTP请求上下文,无法直接获取Session。这种情况下,必须在事件触发前(如用户提交订单时)将Session中的关键数据持久化到订单自定义字段、扩展字段或关联实体中,后续在异步事件中直接从这些存储位置读取数据。
关键注意事项
- 避免依赖全局Session,尽量将临时数据与具体业务实体(如订单、客户)绑定
- 优先使用
SalesChannelContext或业务实体传递数据,减少对请求级Session的依赖 - 异步事件必须提前持久化所需的Session数据,否则无法在异步阶段获取
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

