Composer scripts中直接写zip命令易失败,因环境缺失zip/unzip、参数兼容性差且无错误捕获;应封装为PHP脚本调用ZipArchive或改用git archive打包。

composer scripts 里写 zip 命令会失败?先确认执行环境
直接在 scripts 里写 zip -r app.zip . 很可能失败,不是语法错,而是 shell 环境不可靠:Windows 没 zip、CI 环境没装 unzip 包、macOS 的 zip 不支持 -x 排除参数。更麻烦的是,scripts 不自动加载项目 autoloader,也没办法做条件判断或错误捕获。
真正能落地的做法是把打包逻辑封装成独立脚本,再由 Composer 调用:
- 新建
scripts/archive.php,开头require __DIR__.'/../vendor/autoload.php'; - 用
PharData或ZipArchive类可控地添加文件、跳过node_modules/、.git/、tests/等路径 - 在
composer.json的scripts中定义:"archive": "php scripts/archive.php" - 运行
composer run archive(Composer 2.2+)或composer run-script archive(旧版)
为什么不能直接用 composer archive?它根本不存在
composer archive 命令会报错:Command "archive" is not defined. Composer 官方没有这个内置命令,所有声称“Composer 自带打包功能”的教程,基本混淆了 git archive、手动 tar 或自定义脚本。你查不到文档,也找不到源码实现——因为它压根没被设计出来。
Composer 的职责边界很清晰:管理依赖、生成 autoloader、触发钩子。归档是发布环节的事,得靠外部工具协作完成。强行塞进 scripts 字符串里,只会让构建变得脆弱且难调试。
git archive 比 zip 更适合发版打包
如果你项目用 Git 管理,git archive 是最干净的打包方式——它只打包当前 commit 的源码快照,天然排除 vendor/、.git/、node_modules/ 等非 tracked 文件。
配合 .gitattributes 可以进一步控制归档内容:
- 在项目根目录加
.gitattributes,写入:vendor/** export-ignore、tests/** export-ignore、.env export-ignore - 运行
git archive --format=zip --output=release-1.2.0.zip v1.2.0,tag 打包可追溯 - 注意:
vendor/不在 Git 中,所以打包后必须在目标环境单独运行composer install --no-dev --optimize-autoloader
打包前必须做的三件事:autoload、.env、验证
很多人打包完就上传,结果部署时报 Class not found 或 undefined index: DB_HOST——问题往往出在三个被忽略的环节:
- 打包前必须运行
composer dump-autoload --optimize --no-dev,否则 autoload_classmap.php 不生成,生产环境加载极慢甚至失败 -
.env文件默认不会被git archive打进去(如果没加到.gitignore就危险了),但也不能让它混进归档;正确做法是用.env.example替代,并在部署后手动配置 - 打包后别急着上传,进临时目录执行
php -r "require 'vendor/autoload.php'; echo 'OK';",确认能正常 require,再跑一次最小化启动逻辑(比如new AppKernel();)
最常被绕过的其实是最后一步:没验证就上线。一个没 require 成功的包,压缩得再小也没用。











