Composer 不提供热重载能力,因自动加载依赖静态映射表(如 autoload_psr4.php),PHP 进程启动后仅查该“快照表”,不检测磁盘文件变更;修改类需执行 composer dump-autoload -o 并重启进程或显式刷新加载器。

Composer 本身不提供运行时类文件热重载能力,长生命周期进程(如 Worker、Daemon、Swoole Server)中新增或修改类后,必须手动触发 composer dump-autoload,且需重启进程或显式刷新加载器才能生效。
为什么 PHP 进程不会自动感知类文件变更
Composer 的自动加载基于静态映射表(autoload_psr4.php、autoload_classmap.php),这些文件在 composer dump-autoload 时一次性生成,之后全程只读。PHP 进程启动后,ClassLoader 实例已注册进 spl_autoload_register() 队列,后续所有类加载都查这张“快照表”,不检查磁盘文件是否变动。
- 即使你改了
src/Service/Cache.php或新增了src/Command/Export.php,只要没执行dump-autoload,映射表里就没有对应条目 - Worker 进程 fork 后共享同一份 autoload 数据,子进程也不会重新扫描文件系统
- PSR-4 是路径拼接逻辑,不是实时
file_exists()检查——它只按规则构造路径,然后require;路径错或文件不存在就直接Class not found
常见错误:试图用 require_once 或 include 强制重载
在长进程里写 require_once 'vendor/autoload.php' 多次,不仅无效,还可能引发重复注册警告甚至致命错误:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
vendor/autoload.php只做一次注册(ClassLoader::getLoader()),第二次调用返回已有实例,不刷新映射 - 如果手动
unset($loader)再重 require,会破坏 SPL 注册链,导致后续所有类加载失败 -
include或require类文件本身也不行:PHP 不允许重复定义类,Cannot declare class Xxx, because the name is already in use
可行的绕过方案与注意事项
没有银弹,但可根据场景选择务实解法:
- 开发阶段用
inotifywait+composer dump-autoload -o+ 进程重启(如 Supervisor 的supervisorctl restart),适合 CLI Worker - Swoole 场景下,可在
onWorkerStart回调里调用opcache_invalidate()清理 OPCache,并确保每次请求前重新 require 自动加载器——但这仅对未被 opcache 缓存的文件有效,且不能解决 classmap 缺失问题 - 若必须动态加载新类(如插件机制),放弃 PSR-4,改用
autoload.files配置 + 手动require单个文件,或用eval()/include加载字符串代码(不推荐生产) - 最稳妥方式仍是:修改类 →
composer dump-autoload -o→ 发送信号或调用接口通知进程 reload(如 Swoole 的reload())
真正容易被忽略的点是:classmap 模式下,-o 参数不是可选优化项,而是必需动作——不加它,dump-autoload 根本不会扫描新文件,映射表永远 stale。

















