composer install --no-dev必须加,否则会混入phpunit等dev包,增大体积、引发autoload冲突及rce风险;它硬性跳过require-dev解析,不下载不解压不写classmap。

composer install --no-dev 为什么必须加
不加 --no-dev,vendor/ 目录里会混入 PHPUnit、phpstan、friendsofphp/php-cs-fixer 这类开发期工具,它们不仅增大部署包体积(常多出 20–50MB),还会在运行时触发不必要的自动加载扫描。更关键的是,某些 dev 包的 autoloader 会注册全局函数或扩展钩子,在生产环境里可能引发冲突或未定义行为。
常见错误现象:composer install 后部署到服务器,PHP-FPM 日志里突然出现 Call to undefined function PHPUnit\Framework\assertThat() —— 这说明某个生产代码误用了 dev 包里的函数,而该函数本不该存在。
-
--no-dev是硬性开关,不是可选优化:它直接跳过require-dev节点解析,不下载、不解压、不写 autoload_classmap.php - CI/CD 流水线中必须显式声明,不能依赖本地
composer.json的注释或条件判断 - 如果项目用到了
autoload-dev里的测试辅助类(比如tests/Helper/TestCase.php),需确保这些路径没被生产代码require或use
vendor 目录路径能不能改,怎么改才安全
可以改,但不能靠移动目录或软链“事后补救”。Composer 只认 vendor-dir 配置项,且该配置只在 composer.json 根级生效:
{
"config": {
"vendor-dir": "lib/vendor"
}
}
这个改动会影响整个项目生命周期:从 composer install 到 autoload 生成,再到框架(如 Laravel)的 bootstrap/autoload.php 加载逻辑。一旦改了,所有依赖路径都得跟着重算。
容易踩的坑:
- 改完后没清缓存,
composer dump-autoload仍按旧路径生成映射,导致类找不到 - 某些框架(如 ThinkPHP8)的启动脚本硬编码了
vendor/autoload.php,需同步修改入口文件 - CI 环境里若用
--no-cache,新vendor-dir配置可能被忽略,因为 Composer 会优先读取已存在的composer.lock中记录的旧路径
如何让 vendor 不进 Git,又不影响部署一致性
答案不是靠 .gitignore,而是靠 composer.lock + 显式安装流程。vendor 目录本身就不该进 Git,但很多人误以为“忽略掉就完了”,结果上线时 composer install 拉下来的版本和本地不一致。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
真正起作用的是 composer.lock 文件:它锁定每个包的精确版本、哈希值、源类型(dist 或 source)。只要它存在且未被修改,composer install 就不会重新解析依赖树。
- 确保
composer.lock提交进 Git,且每次composer update后都提交它 - 部署脚本里必须用
composer install --no-dev --prefer-dist --optimize-autoloader,不能用update—— 后者会无视 lock 文件并重新计算 - 如果项目用了 path 类型仓库(比如本地开发的
./packages/my-utils),composer.lock里会记录相对路径;换机器部署时,该路径必须真实存在,否则安装失败
生产环境要不要启用 symlink
不要。symlink 在生产环境是隐患,不是优化。
Linux/macOS 下默认启用软链,但它的行为受三重限制:系统权限、Composer 版本、以及是否在容器里运行。Docker 容器里 vendor/ 软链指向宿主机路径几乎必然失败;Kubernetes Pod 重启后软链目标消失;Windows Server 上若没开开发者模式,symlink: true 会静默退化为复制,反而浪费磁盘。
正确做法是禁用:
composer config --global path.repo.symlink false
或者在 repositories 条目里显式设 "options": {"symlink": false}。这样所有 path 仓库都会被复制进 vendor/,部署时路径稳定、可审计、无权限死角。










