最稳方案是直接复制vendor目录,前提是源机与目标机的php版本、扩展(如ext-zip、ext-openssl)、cpu架构完全一致;打包前需执行composer install --no-dev --optimize-autoloader,并删除vendor/bin/和vendor/composer/installed.json;验证方式为解压后运行test.php检查autoload是否正常。

直接复制 vendor 是最稳的自包含方案
只要源机和目标物理机的 PHP 版本(含小版本,如 8.2.12)、已启用扩展(ext-zip、ext-mbstring、ext-openssl 等)、CPU 架构(x86_64 / aarch64)完全一致,vendor/ 目录就是天然的“自包含离线包”——它不依赖任何网络、不依赖 Composer 运行时解析,解压即用。
常见错误现象:Class not found 或 require(): failed to open stream,往往不是 vendor 缺文件,而是 autoload 未刷新或路径污染。
- 打包前,在源机执行:
composer install --no-dev --optimize-autoloader - 删掉 vendor 中易出问题的路径:
vendor/bin/(Windows 软链在 Linux 失效)、vendor/composer/installed.json(含绝对路径,跨机触发 autoload 异常) - 验证方式:新建空目录 → 解压 vendor → 写
test.php:require 'vendor/autoload.php'; echo class_exists('Monolog\Logger') ? 'OK' : 'FAIL';→ 能输出 OK 才算过关
用 artifact 仓库导入本地 ZIP 包(适合需增量更新场景)
当你要保留 composer install 流程、或后续可能添加新包时,artifact 是唯一原生支持、零额外服务的离线方案。它不走 HTTP,只读本地 ZIP 文件,但对命名和结构极其严格。
常见错误现象:Package not found 却明明 ZIP 已放好,本质是文件名或路径不匹配。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- ZIP 文件必须放在单一目录下(如
./packages/archives),不能嵌套子目录 - 文件名格式必须为:
vendor-name-package-name-version.zip(全部小写,短横线分隔,例如:monolog-monolog-2.10.0.zip) -
composer.json中 require 的版本号必须字面完全一致,写"^2.10"就找不到2.10.0;必须写"2.10.0" - 在
composer.json顶部加仓库声明:{"repositories": [{"type":"artifact","url":"./packages/archives"}]} - 目标机执行:
COMPOSER_DISABLE_NETWORK=1 composer install --no-plugins --no-scripts --no-autoloader
为什么 composer install --no-install 不适合做“自包含包”
--no-install 只下载 ZIP 到缓存(~/.composer/cache/files/、repo/、archived/),不解压也不生成 vendor。它产出的是“依赖原料”,不是“可运行包”。真要靠它离线部署,你得把整个缓存目录打包 + 在目标机精确还原路径 + 配置 cache-dir 全局指向该路径 —— 实操中极易因路径错位、权限丢失、缓存元数据损坏而 fallback 到联网请求。
更现实的问题:缓存里 ZIP 文件没有版本归属上下文,repo/https---packagist.org/packages.json 一旦损坏或缺失,Composer 就无法映射 “哪个 ZIP 对应哪个包”,直接报错退出。
- 不要只拷
files/子目录 ——repo/和archived/缺一不可 - 不同 Composer 版本(如 2.7.x vs 2.9.x)缓存结构有差异,跨版本迁移大概率失败
- 内网机若没设
COMPOSER_CACHE_DIR,Composer 会回退到默认路径,导致缓存不可见
物理机离线部署最容易被忽略的三件事
不是“拷过去就能跑”,而是“拷过去后环境是否真正等价”。很多失败发生在看似无关的细节上。
-
vendor/autoload.php依赖当前工作目录生成路径,如果目标机解压后项目根目录层级变了(比如从/app改成/opt/myapp),autoload 可能加载失败 —— 解压后务必补一记:composer dump-autoload -o - PHP 的
disable_functions或open_basedir限制可能屏蔽file_get_contents或unzip,导致 autoload 初始化失败,需提前检查 php.ini - 某些包(如
symfony/flex、phpstan/extension-installer)会在post-install-cmd里偷偷联网 —— 即使你用了--no-scripts,插件本身也可能在初始化阶段触发请求,所以--no-plugins必须带上










