composer install严格按composer.lock安装确定版本,确保环境一致;composer update忽略lock文件,重解composer.json依赖并更新lock,可能引入不兼容变更。

composer 是一个 PHP 命令行工具,不是函数、库或服务,而是一个可执行二进制程序(通常安装为全局命令),用于声明、解析、下载、安装和管理 PHP 项目的依赖包。
它不依赖 Web 服务器或 PHP-FPM,只要系统有 PHP CLI 环境(≥7.4)就能运行;执行时会读取项目根目录下的 composer.json 和 composer.lock,再操作 vendor/ 目录。
composer install 和 composer update 的本质区别
这两个命令看似都“装依赖”,但触发逻辑、输入依据和副作用完全不同:
-
composer install严格按composer.lock文件还原依赖树——哪怕composer.json里写了"monolog/monolog": "^3.0",只要 lock 里锁的是3.1.2,就只装3.1.2。没有 lock 文件时,它会先生成 lock 再安装,行为等价于composer update --lock。 -
composer update忽略 lock 文件(除非加--with-dependencies等限制),重新解析composer.json中所有约束,调用 SAT 求解器计算最新兼容版本组合,然后更新 lock 并重装 vendor。一次update可能升级几十个包,也容易引入 BC break。 - CI/CD 流水线中必须用
install(保证可重现),本地开发调试才用update(主动尝新)。 - 执行后
composer.lock是否被修改,是判断命令是否真正“变更依赖”的唯一可靠依据。
autoload 机制不是“自动包含”,而是类名到文件路径的映射表
很多人以为 vendor/autoload.php 是靠 include 把所有类一股脑加载进来——完全错误。它实际注册的是 PSR-4 / PSR-0 / classmap / files 四种自动加载器,仅在 new 或 class_exists() 触发时按需定位并 require 单个文件。
- PSR-4 映射由
"autoload": {"psr-4": {"App\": "src/"}}定义,new App\User()→ 自动尝试加载src/User.php。 - 执行
composer dump-autoload -o会把 PSR-4 映射编译成静态数组(vendor/composer/autoload_classmap.php),跳过字符串替换逻辑,提升 20%~30% 类加载性能。 - 若类文件未按命名空间+目录结构严格对齐(比如
src/Helper/Str.php里定义了AppHelperStringHelper),autoload 就会失败——这不是 Composer bug,是 PSR-4 规范强制要求。
scripts 字段里的命令,只在根 composer.json 中生效
你在依赖包(如 monolog/monolog)的 composer.json 里写的 "post-autoload-dump": "Monolog\Handler\ConsoleHandler::init",不会在你的项目中执行。Composer 明确禁止跨包触发脚本,这是安全边界。
- 只有你项目根目录的
composer.json中scripts下定义的内容才会被执行。 -
post-install-cmd和post-update-cmd是最常用钩子,适合做缓存预热、配置生成、权限修复(如chmod -R 755 storage/)。 - PHP 回调必须是
public static方法,且签名必须接收ComposerScriptEvent参数,否则直接报Call to undefined method错误。 - 写 shell 命令时别省略
php前缀:用"phpunit --testsuite=unit",而不是"phpunit --testsuite=unit"—— 后者在 Windows 或 PATH 不含 php 的环境会失败。
关键点始终落在:lock 文件是真相,autoload 是懒加载,scripts 是单向根作用域。任何想绕过这三层机制的“技巧”,最终都会在协作或部署时暴露问题。


















