composer archive 只打包 composer.json 中 autoload 和 include-path 指定的源码目录(如 src/),不包含 vendor/、composer.lock 或配置文件;需通过 extra.archive-includes 白名单添加 config/ 等额外路径,且离线部署仍须运行 composer install。

archive 命令到底打什么包?
composer archive 不打包 vendor/,也不包含 composer.lock 或配置文件 —— 它只按 composer.json 的 "autoload" 和 "include-path" 规则,把当前项目里被声明为“源码”的部分(比如 "src/")打成 zip/tar。你写的是什么,它才打包什么。
- 默认只打包
"src/"目录(如果"autoload": {"psr-4": {"App\": "src/"}}存在) - 不打包
tests/、docs/、.git/,哪怕它们在项目根目录下 - 打包结果不含
composer install所需的任何元信息,离线部署时仍需手动运行composer install --no-dev --prefer-dist
怎么让 archive 包含额外目录(比如 config/ 或 migrations/)?
靠 "archive": {"exclude": [...]} 不行 —— 这个字段只用于排除,不能新增。真正起作用的是 "extra" 下的 "archive-includes",它是白名单机制:
{
"extra": {
"archive-includes": [
"config/**/*",
"migrations/*.php",
".env.example"
]
}
}
- 路径是相对于项目根目录的 glob 模式,支持
**和* - 不支持正则,不支持排除子路径(比如
"config/**/*" + !config/local.php无效) - 如果同时用了
"autoload"和"archive-includes",两者内容会合并打包 - 注意:.gitignore 里的规则对
archive无影响,它完全不读取 .gitignore
打包后缺少 autoload 自动加载逻辑?
因为 composer archive 输出的是纯静态文件,不生成 vendor/autoload.php,也不重写命名空间映射。如果你指望解压后直接 require 'vendor/autoload.php',会报错 —— 那个文件根本不在包里。
- 离线环境必须先执行
composer install --no-dev --prefer-dist(用原始composer.json和composer.lock) - 或者改用
composer dump-autoload --classmap-authoritative提前生成扁平类映射,再把vendor/一起塞进分发包(但这就不是archive干的事了) - 常见误操作:把 archive 包当成可运行的“发布版”,结果 require 失败,卡在
Class not found
压缩格式和性能差异:zip vs tar
默认是 zip,加 --format=tar 可切 tar;但两者在 PHP 层解压效率几乎没差别,关键区别在跨平台兼容性:
- Windows 用户解压
.tar时容易遇到路径过长或权限位乱码(尤其含./开头的文件) -
.zip在所有系统上解压行为最一致,且支持中文文件名(PHP 7.4+ 默认启用zip://UTF-8 支持) - 不要用
--format=tar --compression=gz组合:虽然合法,但tar.gz文件名不会自动带.tar.gz后缀,容易混淆
离线分发真正麻烦的从来不是打包动作本身,而是 autoload 逻辑是否与目标环境匹配、第三方依赖是否锁死、以及开发者误以为 archive = build。










