webman自定义组件分app-plugin和composer-plugin两类,混用会导致配置不加载、路由失效等问题;app-plugin需遵循控制器命名与路径规范并显式注册路由,composer-plugin必须声明type为composer-plugin且实现plugininterface,配置读取须带plugin前缀。

Webman 的“自定义组件”本质就是插件,但必须分清两类:一类是面向业务的 app-plugin(应用型插件),另一类是面向技术复用的 composer-plugin(Composer 插件)。混用会导致配置不加载、路由不注册、甚至 composer install 后完全静默失效。
app-plugin 创建后访问 404?检查路由和控制器命名规范
执行 php webman app-plugin:create dingdingtalk 后,目录生成成功不代表能直接访问。常见失败原因是:
- 控制器类名未严格遵循
IndexController,或没放在plugin/dingdingtalk/app/controller/下 -
route.php中未显式注册路由,比如漏写Route::get('/app/dingdingtalk', [IndexController::class, 'index']) - 启动服务前没执行
php webman restart或php webman start -d,缓存未刷新 - 访问路径写成
/dingdingtalk而非约定的/app/dingdingtalk
验证方式:直接在浏览器打开 http://127.0.0.1:8787/app/dingdingtalk,返回 404 就说明路由没通;返回 500 则大概率是控制器里抛了异常。
composer-plugin 不生效?type 和 extra.class 缺一不可
如果你把插件发布到 Packagist 并用 composer require tinywan/encryption 安装,但 config/plugin/tinywan/encryption/ 目录没自动创建,或 config('plugin.tinywan.encryption.app') 返回 null,问题几乎一定出在 composer.json:
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
- 必须声明
"type": "composer-plugin"—— 写成"library"或漏掉这一行,Composer 根本不会调用你的插件类 - 必须声明
"require": {"composer-plugin-api": "^2.0"},不是composer/composer -
"extra": {"class": "Tinywan\Encryption\Plugin"}中的类必须存在、可 PSR-4 自动加载,且该类要实现ComposerPluginPluginInterface - 不要在插件代码里手动
require vendor/autoload.php,这会破坏 Composer 的加载上下文
调试技巧:运行 composer show tinywan/encryption,看输出里是否含 type : composer-plugin;再执行 composer dump-autoload -o 确保自动加载映射更新。
插件配置读取不到?注意 config() 的 key 命名规则
Webman 插件配置合并后,并不直接挂到根命名空间下。哪怕你插件里写了 config/app.php,也不能用 config('app.level') 读取,而必须带完整插件路径前缀:
- 插件路径为
vendor/tinywan/encryption/→ 配置文件在config/plugin/tinywan/encryption/app.php→ 正确读法是config('plugin.tinywan.encryption.app.level') - 插件路径为
plugin/dingdingtalk/→ 配置在plugin/dingdingtalk/config/app.php→ 读法仍是config('plugin.dingdingtalk.app.level')(plugin前缀统一) - 如果读出来是
null,先确认该配置文件是否返回一个数组,而不是直接 echo 或 return 语句错误
容易忽略的一点:config() 是运行时函数,不能在 bootstrap.php 或进程启动前就调用它来初始化全局变量——此时配置可能还没合并完成。
真正卡住人的地方往往不是语法,而是 Webman 对插件类型的强约束:app-plugin 依赖 console 命令生成结构,composer-plugin 依赖 Composer 的 type 识别机制,二者不能互相替代。选错类型,后面所有开发都建立在流沙之上。










