composer install 严格按 composer.lock 安装,保障多环境一致;composer update 仅用于主动升级依赖,否则易引发版本漂移、class not found 或 servicenotfoundexception 等问题。

composer install 和 composer update 在 symfony 项目里不能混用
在 Symfony 项目中,composer install 是部署和协作的标准动作;composer update 只该在明确要升级依赖时手动触发。一旦 composer.lock 已存在,install 就会严格按锁文件安装——这是 Symfony 多环境稳定运行的前提。
常见错误现象:composer update 后本地能跑,CI 或生产环境报 Class not found 或 ServiceNotFoundException;根本原因是 dev 依赖(比如 symfony/debug-bundle)被意外升到不兼容版本,或某个 bundle 的隐式依赖版本漂移。
- CI/CD 流水线必须用
composer install --no-dev --optimize-autoloader - 本地开发若需更新某包,优先指定范围:
composer update symfony/framework-bundle,避免全量刷新 - Symfony flex 安装器(如
symfony/website-skeleton)生成的composer.lock默认含symfony/flex插件逻辑,随意update可能跳过 recipe 执行
symfony/flex 插件不是可选组件,禁用会导致 bundle 配置失效
symfony/flex 是 Symfony 4+ 项目的“配置中枢”,它通过 recipe 机制自动注入配置、创建目录、修改 .env。禁用或卸载它,composer require 就只剩下载代码,不再触发任何集成动作。
使用场景:当你执行 composer require doctrine/doctrine-bundle,Flex 会自动写入 config/packages/doctrine.yaml 并创建 migrations/ 目录;没有 Flex,这些全得手写,且容易漏掉 doctrine.orm.auto_generate_proxy_classes 这类关键开关。
- 检查是否启用:
composer show symfony/flex输出应为已安装状态;若为dev-main或高版本(如2.4.5),基本没问题 - 禁用方式(
composer config extra.symfony.allow-contrib false)只应在极少数合规审计场景下临时使用,且必须同步手工补全所有 recipe 内容 - Flex 的
recipes数据源来自https://github.com/symfony/recipes,国内网络不稳定时,composer require卡住多半是这里超时,可临时加--no-scripts跳过,再手动处理
autoload 配置写错会让 Symfony 找不到 Controller 或 Entity
Symfony 不靠文件路径自动加载类,而是依赖 composer.json 中的 autoload 和 autoload-dev 声明。写错映射规则,php bin/console debug:container 就查不到服务,php bin/console make:controller 生成的类也进不了 autoloader。
典型错误:把 App 命名空间映射到 src/ 时,漏掉尾部斜杠或大小写不一致;或者在 autoload-dev 里重复声明了 App,导致 prod 环境加载了测试专用类。
- 标准写法(Symfony 6+):
"autoload": { "psr-4": { "App": "src/" } } - Entity 类若放在
src/Domain/User/Entity,命名空间必须是AppDomainUserEntity,且autoload里不能只写"App": "src/"—— 它已覆盖全部子目录 - 运行
composer dump-autoload --optimize后,检查vendor/composer/autoload_psr4.php是否包含你期望的映射,这是最直接的验证方式
prod 环境下 composer install –no-dev 仍可能加载 dev 依赖
表面上 --no-dev 会跳过 require-dev,但某些包(尤其是带 scripts 的)会在 post-install-cmd 阶段偷偷 require dev 工具。最典型的是 symfony/web-server-bundle(已废弃)或自定义的 post-install-cmd 脚本调用了 phpstan。
性能影响:dev 包被加载后,即使没执行,也会增加 autoloader 映射体积,opcache.preload 失效风险上升;更严重的是,某些 dev 包的 service provider 会注册到容器中,在 prod 下触发未预期行为。
- 检查方式:
composer show --dev查看当前装了哪些 dev 包;再搜composer.json的scripts字段,看有无post-install-cmd或post-update-cmd - 安全做法:所有
scripts必须加条件判断,例如"@php -r "if (!getenv('SYMFONY_ENV') || getenv('SYMFONY_ENV') !== 'prod') { ... }"" - 终极隔离:CI 中用
composer install --no-dev --no-scripts,后续再单独跑需要的脚本(如php bin/console cache:warmup)
Flex 的 recipe 执行时机藏在 composer install 的末尾,不是每次都会触发;如果你改过 composer.lock 或跳过脚本,那个自动配置就真的没了——得自己翻 recipe 源码补。