Webman插件生效需严格遵循加载契约、配置合并规则与生命周期钩子;跳过任一环将导致失效或冲突。config/plugin/{vendor}/{name}/下同名配置项才合并,boot()是唯一可靠入口,类自动加载须PSR-4规范,配置热更新需重启进程。

Webman 的插件系统不是靠“加个目录就能用”,而是依赖明确的加载契约、配置合并机制和生命周期钩子——跳过其中任一环,插件大概率不生效或引发配置冲突。
插件目录结构与 config/plugin 自动合并规则
Webman 只识别 config/plugin/{vendor}/{name} 下的配置文件,且仅合并同名配置项(如 middleware.php 合并进主项目的 config/middleware.php),不会覆盖整个数组。常见错误是把插件配置直接扔进 config/ 根目录,或误以为插件能修改 bootstrap.php 的执行顺序。
- 插件配置必须放在
config/plugin/{vendor}/{name}/,例如config/plugin/tinywan/encryption/middleware.php - 配置键名需与主项目一致(如
'http' => [...]才会合并进config/server.php的http字段) - 若插件需注册自定义进程,
process.php中返回的数组会被追加到主config/process.php,但不会去重 —— 多个插件注册同名进程会导致启动失败
registerPlugin() 与插件生命周期的实际触发时机
Webman 没有全局 registerPlugin() 函数;插件的“注册”本质是 Composer 自动加载 + 配置扫描 + 容器绑定。真正起作用的是插件在 src/Plugin.php 中实现的 boot() 方法,它在框架 Worker::run() 初始化完成后、事件循环开始前被调用。
-
boot()是唯一可靠入口,适合绑定事件监听、注册命令、初始化共享服务 -
init()不是标准生命周期方法,手动定义也不会被自动调用 - 插件无法拦截
onWorkerStart等 Worker 级回调,除非显式在boot()中通过Worker::$onWorkerStart赋值 —— 但要注意多个插件赋值会相互覆盖
动态加载插件时的类自动加载陷阱
插件内类默认走 Composer PSR-4 自动加载,但若插件使用了非标准命名空间(如 TinywanEncryption 却声明为 tinywan/encryption 包名),或未在 composer.json 中正确配置 "autoload",就会出现 Class not found 错误,且错误堆栈常指向 config/plugin/ 加载过程,掩盖真实原因。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
- 检查插件根目录
composer.json是否包含有效 autoload 声明,例如:"autoload": {"psr-4": {"Tinywan\Encryption\": "src/"}} - 运行
composer dump-autoload确保映射更新,尤其在开发阶段频繁修改命名空间时 - 避免在插件中 require 绝对路径文件(如
require '/var/www/app/config.php'),这会破坏可移植性
插件间通信与 sharedState 的实际限制
Webman 官方未提供 sharedState 对象,所谓“共享状态”只能靠开发者自行约定:通常用 Container::get('plugin_state') 或全局静态属性模拟,但这极易引发竞态和内存泄漏。
- 跨插件数据传递应尽量走事件总线(
Event::fire()),而非直接读写全局变量 - 若必须共享对象,建议用单例容器绑定,并在
boot()中初始化,避免重复构造 - 不要在插件中监听
onConnect或onMessage等 TCP 层事件后长期持有客户端连接引用 —— 这会导致连接无法释放,最终耗尽 Worker 连接池
最易被忽略的一点:插件的 config/plugin/xxx/xxx.php 文件在 Webman 启动时被一次性读取并缓存,后续热更新(如改完配置再 php start.php reload)不会重新加载 —— 必须重启 Worker 进程才能生效。










