Composer 通过 autoload-dev 实现开发与生产配置分离:autoload 下的配置始终生效,autoload-dev 中的路径仅在启用 dev 模式(未加 --no-dev)时加载;生产环境执行 composer install --no-dev 后,dev 类不会被自动加载,因此必须由应用层根据环境变量动态实例化对应配置类,且开发专用依赖须严格置于 require-dev 中。

用 composer.json 的 autoload-dev 区分开发与生产配置加载
Composer 本身不提供“环境感知”的自动加载机制,但可以通过 autoload-dev 配置让开发专用文件(如调试配置、Mock类)只在 composer install --dev 或本地运行时加载,而不会进入生产部署包。
关键在于:生产环境执行 composer install --no-dev 后,autoload-dev 中定义的路径和 PSR-4 映射将被完全忽略,对应文件不会写入 vendor/autoload.php,也不会被自动加载器识别。
-
autoload下的配置始终生效(适用于所有环境) -
autoload-dev下的配置仅在启用了 dev 模式时生效(即未加--no-dev) - 不要把生产必需的配置文件放在
autoload-dev里,否则上线后会报Class not found
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Config\\Dev\\": "config/dev/",
"App\\Config\\Prod\\": "config/prod/"
}
}
}
在代码中按环境动态加载配置类
不能依赖 Composer 自动加载“切换配置”,必须由应用层控制——比如在启动时根据 $_ENV['APP_ENV'] 或环境变量决定实例化哪个配置类。
常见错误是直接 new DevConfig() 而不检查环境,导致生产环境因类未加载(或不应加载)而崩溃。
- 确保
DevConfig类只出现在autoload-dev映射中,且不在生产composer install --no-dev的产物里 - 用工厂模式或简单条件判断加载:比如
if ($_ENV['APP_ENV'] === 'dev') { new DevConfig(); } else { new ProdConfig(); } - 避免在全局作用域中无条件 new 开发类,否则即使没调用也会触发 autoload 失败
用 require-dev 管理仅开发环境需要的包
有些配置依赖外部工具(如 phpunit/phpunit、symfony/var-dumper),它们不该出现在生产环境中。这些应严格放在 require-dev 里。
如果误写进 require,即使你没在生产代码中 use 它们,Composer 仍会安装并可能引发安全扫描告警或兼容性问题。
-
require-dev中的包在composer install --no-dev时完全不安装 - 若某包既被开发使用、又被生产配置逻辑间接依赖(例如日志格式化器),它就不是纯 dev 依赖,得移回
require - 运行
composer show --dev可确认当前是否加载了 dev 包
注意 composer dump-autoload 的环境一致性
执行 composer dump-autoload 时,默认包含 dev 加载规则。如果你在 CI/CD 流水线中先运行了该命令再执行 --no-dev 安装,生成的 autoloader 可能残留 dev 映射,导致生产环境意外加载开发类。
- CI 中推荐统一用
composer install --no-dev --optimize-autoloader,跳过手动 dump 步骤 - 本地开发可保留
composer dump-autoload -o提升性能,但别把它提交到部署脚本里 - 检查
vendor/composer/autoload_psr4.php文件内容,确认生产构建后不含Dev\\相关路径
最易被忽略的是:以为只要不 new 就安全,其实只要类名出现在任何已加载文件的 use 或 class_exists() 中,就会触发 autoload —— 而这个 autoload 表是否含 dev 类,取决于当初怎么 install 的。










