PHP观察者模式使用规范是什么

作者:袖梨 2026-07-14
PHP观察者模式应以“解耦、可控、可测”为核心,避免使用简陋的SplSubject/SplObserver,推荐手写轻量EventDispatcher类,支持字符串事件名、传参、callable监听器,并注意无副作用、异步处理及按需选型。

PHP中观察者模式的使用规范,核心是“解耦、可控、可测”,不是照搬接口契约,而是围绕业务真实需求设计轻量通知机制。

避免直接依赖 SplSubject/SplObserver

SPL 提供的 SplSubjectSplObserver 接口过于简陋:

  • 不支持传参,notify() 调用时 observer 拿不到事件上下文
  • 无法区分事件类型,所有通知都走同一个 update() 方法
  • 没有生命周期管理(如 detach、once、priority),难以控制执行顺序或条件
  • 实际项目中容易因未 attach 就 notify 导致 Fatal error: Call to a member function update() on null

建议仅将其作为命名参考,不用于生产逻辑。

推荐手写 EventDispatcher 类

一个零依赖、易测试、可复用的轻量实现更符合 PHP 项目实际:

立即学习“PHP免费学习笔记(深入)”;

  • 用字符串事件名作键,支持多事件注册(如 'user.registered''order.paid'
  • dispatch 时显式传入数据数组,observer 回调可直接解构使用
  • 监听器用 callable 即可,无需定义接口或抽象类,降低侵入性
  • 不绑定容器、不强制继承、不依赖自动发现机制,CLI 脚本或微服务中也能直接用

注意触发时机与生命周期

观察者逻辑应保持无副作用、不阻塞主流程:

  • 禁止在 __construct() 中触发通知,确保 observer 已注册完成
  • 避免在 observer 回调里做耗时操作(如远程 API 调用、文件写入),需异步请交由队列处理
  • 不建议在 observer 中修改 subject 状态,防止循环通知或状态不一致
  • 若需按顺序执行,应在 dispatcher 层加 priority 支持,而非靠注册顺序隐式约定

适配不同项目规模的方案选择

不必强求统一架构,按需选型:

  • 小型脚本或工具类:用函数式回调,如 on_user_login(fn($data) => send_welcome_email($data))
  • 中型项目(无框架):封装 EventDispatcher,配合 PSR-14 兼容接口便于未来升级
  • Laravel 项目:优先用原生 event()dispatch(new UserRegistered($user)),但注意监听器注册位置和作用域
  • 需要跨进程/服务:观察者只发消息到队列(如 Redis List / AMQP),由独立消费者处理

相关文章

精彩推荐