该错误是PHP 8.0+下重复定义常量M_WORKER_DAEMONIZE导致的Fatal error,主因是Worker.php被多次加载(如手动require、宝塔auto_prepend_file注入或子进程重复引入),需用get_defined_constants(true)['user']定位首次定义位置并清除冗余引入。

Workerman报错“M\_WORKER\_DAEMONIZE constant redefined”是什么原因
这个错误不是 Workerman 自身抛出的,而是 PHP 在重复定义常量时触发的致命错误(Fatal error: Constant M_WORKER_DAEMONIZE already defined)。根本原因是项目中多次加载了 Workerman 的核心文件(比如 Worker.php),导致其内部定义的常量被重复执行 define()。常见于手动 require 或 include 了 vendor 中的类文件,或在 Composer 自动加载之外又显式引入了相同路径。
为什么加-d参数后更容易出现这个错误
加 -d 参数会触发 Workerman 的 daemonize 流程,过程中主进程 fork 出子进程,而某些不规范的代码会在子进程中再次加载 Worker.php(例如在 onWorkerStart 里写了 require 'vendor/workerman/Worker.php')。此时常量已由父进程定义过,子进程再定义就直接报错。
- 检查
start.php和所有回调函数(如onWorkerStart、onMessage)里是否手动require或include过Worker.php或Autoloader.php - 确认没在任何地方写
define('M_WORKER_DAEMONIZE', ...)或类似硬编码 - 用
grep -r "require.*Worker.php\|include.*Worker.php" . --include="*.php"全局搜一遍
如何快速定位重复加载点
在项目入口(如 start.php)顶部加一段调试代码,利用 get_defined_constants(true)['user'] 检查常量是否已被定义:
if (defined('M_WORKER_DAEMONIZE')) {
echo "M_WORKER_DAEMONIZE already defined at: " . debug_backtrace()[0]['file'] . "\n";
exit(1);
}
然后运行 php start.php start -d,错误输出会直接告诉你第一次定义该常量的位置。90% 的情况指向某个被意外多次包含的配置文件或工具类。
宝塔面板环境下特别注意
宝塔的「PHP 管理」页面有时会自动注入额外的 auto_prepend_file(比如用于防跨站),如果它里面包含了对 Workerman 类的加载逻辑,就会和你的 start.php 冲突。检查:
- 宝塔 > PHP 设置 > 配置修改 > 搜索 auto_prepend_file
- 若值非空(如指向某个安全模块),临时清空并重启 PHP,再试启动
- 不要在宝塔的「计划任务」里用
php /www/wwwroot/xxx/start.php start -d方式拉起 —— 它可能绕过 Composer autoloader,导致手动 require 补救,反而引发重复加载 - 改用 systemd 或 supervisor 管理更可控,且能明确工作目录和环境变量
常量重定义问题本身不难解,但容易被误判为 Workerman 版本或 PHP 兼容性问题;真正麻烦的是它往往藏在某次临时加的兼容性补丁里,上线后才暴露。动手前先确认整个加载链路里 Worker.php 只被 Composer 自动加载一次。

















