vendor目录不能直接tar因含软链接、.git、dev包及平台扩展;需目标环境执行composer install --no-dev --optimize-autoloader --ignore-platform-reqs后再tar;用composer dump-autoload --classmap-authoritative破除autoload路径依赖。

离线打包时 vendor 目录为什么不能直接 tar -cf?
因为 composer install 生成的 vendor/ 里混着大量软链接(比如 bin/ 下的可执行文件指向 ../vendor/bin/xxx)、.git 目录残留、dev-only 的包(如 phpunit),还有平台相关扩展(如 ext-redis 编译产物)。直接 tar 会把开发机环境“气味”一起打包过去,到目标服务器可能报 Class not found 或 undefined symbol。
正确做法是:在目标服务器相同 OS + PHP 版本的机器上执行打包,且用 --no-dev --optimize-autoloader --ignore-platform-reqs 参数确保干净:
composer install --no-dev --optimize-autoloader --ignore-platform-reqs
再 tar,避免把本地路径、符号链接、测试依赖带进去。
如何让离线包在不同服务器上自动适配 autoload?
Composer 生成的 vendor/autoload.php 默认硬编码了绝对路径(比如 /home/user/project/vendor),一挪位置就失效。这不是 bug,是设计如此——但离线分发时必须破除它。
关键操作只有一步:打包前运行
composer dump-autoload --classmap-authoritative
这会让 autoloader 放弃动态查找,改用预生成的 classmap,彻底脱离路径依赖。同时确保 composer.json 中没写死 autoload.files 绝对路径,所有 psr-4 映射都用相对路径(如 "App\": "src/")。
常见错误现象:Class 'AppHttpControllersController' not found —— 八成是没跑 dump-autoload,或者跑了但没加 --classmap-authoritative。
分发后 composer install 还要重跑吗?
不需要,也不应该。离线包的核心价值就是跳过 composer install。
但要注意三个条件:
- 打包机和目标机的
PHP_VERSION和关键扩展(mbstring、json、openssl)必须一致,否则vendor/composer/autoload_static.php里的类定义可能不兼容 -
composer.lock必须随包一起分发,并放在项目根目录;运行时若检测到 lock 文件变更,某些插件(如hirak/prestissimo)会悄悄触发网络请求 - 如果用了
composer-plugin(比如symfony/flex),它可能在 install 阶段写文件或调 API,这类插件必须提前禁用:"config": {"disable-tls": true, "secure-http": false}不起作用,得删掉插件或用--no-plugins
压缩包解压后权限和用户问题怎么处理?
Linux 下常见问题是:打包机用 root 打的包,解压后 www-data 用户没权限读 vendor/ 里的 .so 文件或写 cache/ 目录;或者 vendor/bin/ 下脚本丢失 x 权限。
实操建议:
- 打包前统一 chown 到普通用户(如
www-data:www-data),再 chmod 755vendor/bin/* - 用
tar --owner=0 --group=0 --numeric-owner打包,避免 uid/gid 错位 - 解压后立刻运行:
find vendor/ -type f -name "*.php" -exec chmod 644 {} ;和find vendor/bin/ -type f -exec chmod 755 {} ;
别指望 umask 或 tar -p 自动搞定——不同发行版默认行为差异太大,手动加固最稳。
最麻烦的其实是 PHP 扩展 ABI 兼容性:同一版本 PHP,但打包机是 Ubuntu 22.04(glibc 2.35),目标机是 CentOS 7(glibc 2.17),ext-igbinary 这种带 .so 的包一加载就 Segfault。这种没法靠打包技巧绕过,只能确保基础环境一致。










