composer dump-autoload 不能解决自动加载变慢问题,因为 ThinkPHP 不完全依赖 Composer 自动加载,还叠加框架自身 Loader::addNamespace、addMap 及动态注册逻辑;历史模块删除后若未清理注册,类名仍入队列,导致多次 file_exists 磁盘扫描——这才是性能瓶颈根源。

为什么 composer dump-autoload 不能解决自动加载变慢问题
因为 ThinkPHP 的自动加载不完全依赖 Composer 的 autoload_classmap 或 psr-4,它还叠加了框架自身的 Loader::addNamespace、Loader::addMap 和运行时动态注册逻辑。一旦历史模块被删但未清理对应注册,类名仍会进加载队列,最终触发 file_exists 多次磁盘扫描——这才是慢的根源。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 检查
app/extra/下是否残留已废弃模块的配置文件(如wechat.php),它们可能在启动时调用Loader::addNamespace - 搜索整个项目中是否硬编码调用了
Loader::addMap或Loader::addPsr4,尤其在common.php、provider.php或服务提供者里 - 运行
php think clear:route和php think clear:config后,再手动删掉runtime/cache/和runtime/container/目录(ThinkPHP 不会自动清 container 缓存中的加载映射)
如何安全识别并删除“已下线但仍在 autoload 中注册”的类
直接删代码风险高,得先确认哪些类真没人用了。ThinkPHP 没有内置“未使用类扫描”,但可以借力 PHP 的反射和日志反推。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 临时开启
trace并复现典型请求,在runtime/log/里搜ClassNotFoundException或Warning: require(): failed to open stream,这些是“注册了但文件已删”的铁证 - 在
base.php开头加一行:ini_set('log_errors', '1'); error_log("Loaded: " . $class . "\n", 3, '/tmp/think-loaded.log');(仅调试用),跑几轮核心接口后分析日志去重,没出现过的类大概率可删 - 注意:不要删
think\命名空间下的类,哪怕你没直接 use —— 框架底层可能通过字符串拼接调用(如new $prefix . 'Exception')
composer.json 里删了包,为什么 vendor/ 还有残留文件
Composer 只管自己安装的顶层包,不管子依赖的子依赖是否被其他包复用。比如你删了 topthink/think-captcha,但它依赖的 guzzlehttp/psr7 可能还被 overtrue/socialite 用着,Composer 就不会动它。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 执行
composer show --tree看依赖树,确认目标包是否真无任何引用;再用composer depends guzzlehttp/psr7查谁在依赖它 - 删
vendor/后必须重新composer install,不能只composer update xxx——后者可能跳过已满足的依赖,残留旧文件 - 如果确定要强删,先
rm -rf vendor/topthink/think-captcha,再composer dump-autoload -o,最后检查vendor/composer/autoload_psr4.php里是否还有相关映射行(有就手动删)
部署脚本里漏掉这一步,上线后自动加载会悄悄降级
ThinkPHP 在生产环境默认启用 APP_DEBUG = false,此时类自动加载会走 runtime/classmap.php 缓存。但这个文件不是每次请求都刷新,而是由命令 php think build 或首次访问时生成。如果你部署时只清了 runtime/,没重建 classmap,框架就会退回到逐个 file_exists 扫描模式。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- CI/CD 脚本末尾必须加:
php think build --config-only && php think build --classmap(--config-only避免误重建路由) - 确认
runtime/classmap.php文件生成时间比部署时间新,且内容不为空(至少含return [和若干键值对) - 如果项目用了自定义命名空间(如
app\common\service\),确保build.php配置里'dirs' => ['app']包含对应路径,否则 classmap 不会收录
classmap 不是万能的——它只缓存“能找到的类”,如果某次部署删了类但忘了删 classmap 里的映射,运行时反而会报错。所以每次删代码,都要连带更新 classmap。


















