composer install 更可靠,因它严格按 composer.lock 还原完全一致的依赖树(含版本、子依赖、哈希);而 composer update 会重解析 composer.json,可能连带升级间接依赖并引入 BC break。

composer install 为什么比 composer update 更可靠
因为 composer install 完全按 composer.lock 还原依赖树,每个包的版本、子依赖嵌套、哈希校验都一模一样;而 composer update 会重新解析 composer.json,哪怕只改了一个 ^2.0 到 ^2.1,也可能连带升级十几个间接依赖,引入 BC break 或运行时不兼容。
常见错误现象:
- CI 脚本里写了
composer update,结果线上跑着跑着报Call to undefined method Illuminate\Support\Str::of()(Laravel 9 升 10 的典型断裂点) - 本地
composer update后没提交新的composer.lock,队友composer install装出旧版包,调试半天发现是symfony/console差了 0.3 个小版本
实操建议:
- 所有 CI/CD 构建脚本、Dockerfile 中必须用
composer install,禁用update - 团队成员本地开发也应默认走
install;只有明确要升级依赖时,才运行composer update --lock并立即提交新composer.lock - 检查
composer.lock是否过期:运行composer install --dry-run,若输出 “Installing dependencies from lock file” 说明一致;若出现 “Resolving dependencies…” 就代表composer.json和lock不匹配,需人工干预
config.platform 怎么写才真正生效
config.platform 是控制多环境依赖一致性的核心开关,但它极易写错位置或格式,导致形同虚设。
正确写法必须满足三个条件:
- 必须放在
composer.json根级config对象下,键名严格为platform,不是platform.php、php-platform或嵌套在extra里 - 值必须是对象,且 PHP 版本号写死到小版本,例如
"php": "8.1.10";写"^8.1"、"8.1"或"8.1.0"(末尾缺零)都会被忽略 - 修改后必须删掉旧
composer.lock和vendor/,再执行composer install—— 旧 lock 文件会继续按原来平台解析,不会自动刷新
验证是否生效:
- 运行
composer show php,输出应为name : php version : 8.1.10 - 运行
composer install --dry-run,观察日志中是否出现Platform configuration: php 8.1.10 - 对比两台机器上
vendor/composer/autoload_classmap.php的sha256sum,一致才说明 platform 约束真正起效
COMPOSER_DEV_MODE 和 --no-dev 的实际区别
--no-dev 是部署时最该加的参数,它直接跳过 require-dev 区块的安装行为;而 COMPOSER_DEV_MODE=0 是 Composer 原生支持的环境变量,效果等同但更适配 CI 场景。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
关键事实:
-
--no-dev不影响autoload-dev的定义,只是不装那些 dev 包;但如果你代码里硬写了new \Tests\FooTest(),运行时仍会报Class not found -
COMPOSER_DEV_MODE=0在 Dockerfile 中更可控:ENV COMPOSER_DEV_MODE=0+RUN composer install,避免漏加参数 - 别把生产必需的工具(如
symfony/var-dumper)塞进require-dev后又盲目加--no-dev——它不是“测试专用”的代名词
实操建议:
- Docker 构建镜像时,统一用
composer install --no-dev --optimize-autoloader - CI 流水线中,推荐显式传参:
composer install --no-interaction --platform=php:8.1.10 --no-dev - 禁止搞
composer.prod.json和composer.dev.json分裂配置——Composer 不支持多配置文件切换,会破坏 lock 一致性
vendor/autoload.php 加载不一致的根本原因
别盯着 autoloader-suffix,它只是个自动生成的哈希标识符,不能手动设置,也不影响加载逻辑。真正导致不同环境类找不到的,是三件事没对齐:
-
composer.lock没提交到 Git,导致各环境各自install出不同版本 - PHP 版本或扩展缺失(比如没装
ext-redis),但config.platform又没声明,结果装了依赖却 runtime 报错 - 部署时没加
--optimize-autoloader,导致 PSR-4 映射未转成 classmap,某些路径大小写或符号差异在不同系统上触发失败
快速验证方法:
- 检查
vendor/autoload.php开头几行,确认是否包含require __DIR__ . '/composer/autoload_real.php';—— 这才是真实入口 - 运行
php -r "include 'vendor/autoload.php'; var_dump(class_exists('Psr\Http\Message\RequestInterface'));",结果应为bool(true) - 对比两台环境的
vendor/composer/autoload_classmap.php文件哈希,必须完全相同
真正要盯紧的是 composer.lock 的提交状态、PHP 运行时环境是否对齐、以及部署命令是否加了 --optimize-autoloader。autoloader-suffix 是个影子,它动不动,不影响正事。










