离线环境需预装插件并配置本地仓库:在有网机执行composer install确保插件及依赖完整,打包插件zip,离线机通过repositories指向本地包,且php版本、composer版本、autoload均须一致。

插件依赖在离线环境里根本不会自动下载
Composer 默认所有 composer install 或 composer update 都会联网拉取包,包括插件(比如 hirak/prestissimo、phpstan/extension-installer)。离线时直接报错:Could not fetch https://repo.packagist.org/packages.json,连 metadata 都拿不到,更别说插件本身。
关键点在于:插件本质是普通 Composer 包,但它的安装时机早于主项目依赖——Composer 在解析 composer.json 阶段就尝试加载已声明的插件,此时若插件未本地存在且无法联网,流程立刻中断。
- 必须提前在有网机器上完整安装并固化插件,不能只拷
vendor/目录了事 -
composer.lock必须包含插件的精确版本、hash 和 source 类型(dist还是source) - 离线机上的 Composer 版本要 ≥ 有网机的版本,否则可能不识别锁文件里的插件字段
怎么让插件不触发远程请求?
核心是切断 Composer 对 Packagist 的任何依赖。最可靠方式是用 composer install --no-plugins 跳过插件加载,但代价是插件功能全失效——这通常不可接受。真正可行的是预生成「无网络」可用的 vendor 目录:
- 在有网环境执行
composer install --no-interaction,确保所有插件(含其自身依赖)都下载到vendor/ - 运行
composer archive --format=zip --dir=dist/ my-plugin手动打包每个插件(如phpstan/extension-installer),存为dist/phpstan-extension-installer-1.2.3.zip - 在离线机的
composer.json中,为插件添加repositories条目,类型设为package,指向本地 zip 路径:{ "repositories": [ { "type": "package", "package": { "name": "phpstan/extension-installer", "version": "1.2.3", "dist": { "url": "/path/to/dist/phpstan-extension-installer-1.2.3.zip", "type": "zip" } } } ] }
为什么 vendor/bin 下的插件二进制在离线时可能失效?
很多插件(如 php-cs-fixer、phpstan)会在 vendor/bin/ 写入口脚本,这些脚本内部常硬编码 require 路径或调用 Composer\Autoload\ClassLoader。离线环境下若 autoload 未正确生成,或插件依赖的其他包缺失,就会报 Class not found 或 require(): failed to open stream。
- 务必在有网机上执行
composer dump-autoload --optimize,生成优化后的vendor/composer/autoload_classmap.php - 检查
vendor/bin/中对应脚本第一行是否为#!/usr/bin/env php,且后续require的路径是相对__DIR__的,而非动态拼接 - 离线机 PHP 版本需与有网机制作环境一致,否则
opcache或语法兼容性会导致脚本静默失败
离线部署后验证插件是否真生效?
别只看 composer install 是否成功——它可能跳过插件加载却假装完成。必须触发插件实际行为:
- 对
phpstan/extension-installer,运行vendor/bin/phpstan analyse --version,输出应含extensions installed提示 - 对
hirak/prestissimo,执行composer install -v,日志中应出现Using Prestissimo字样,而非Downloading... - 如果插件注册了
PluginInterface,可在vendor/composer/autoload_plugins.php中确认其类名和路径是否被正确注册
最容易被忽略的是插件自身的依赖树:比如 phpstan-extension-installer 依赖 phpstan/phpstan,后者又依赖一堆分析器包。这些二级依赖必须全部提前下载好,否则离线时只差一个包,整个插件就卡死。










