必须提前安装对应installer(如wpackagist/installer)、确保包type匹配、配置extra.installer-paths映射,三者缺一不可;require本身不指定installer,满足条件后自动触发。

require 时怎么让包走自定义 installer
Composer 不会在 require 命令里直接指定 installer,installer 的触发完全由包自身的 type 字段 + 项目中已安装的 installer 包共同决定。你不能在 composer require vendor/package:1.2.3 后面加参数“告诉它用哪个 installer”,只能提前铺好条件。
常见错误现象:加了 installer-paths 配置,require 也成功了,但包还是进了 vendor/——根本原因是该包的 type 没被任何已安装的 installer 识别。
- 先确认你要装的包在 Packagist 上声明的
type(比如wpackagist-plugin/akismet的type是wordpress-plugin) - 运行
composer require wpackagist/installer(或composer/installers,取决于 type 类型) - 确保你的项目
composer.json的extra.installer-paths里有对应映射,例如:"wp-content/plugins/{$name}/": ["type:wordpress-plugin"] -
require命令本身不带 installer 参数,只要上述三点满足,安装时自动走匹配的 installer
为什么 composer/installers 一定要手动 require
composer/installers 不是 Composer 内置功能,它只是一个提供通用 type 映射规则的 PHP 包。没有它,type:cakephp-plugin 或 type:myapp-extension 这类声明就只是字符串,没人解析、没人响应。
它的作用不是“帮你装包”,而是“让 Composer 知道:当看到某个 type,就按这个路径模板放”。所以它必须出现在你项目的 vendor/ 里,且在 require 流程早期被加载。
- 不装
composer/installers,即使installer-paths配对正确,也完全无效 - 只装
wpackagist/installer不代表支持所有 WordPress 相关 type,它只处理wordpress-plugin、wordpress-theme等明确声明的类型 - 私有包想走自定义路径?必须在包自己的
composer.json里设"type": "myapp-extension",再在根项目补上composer/installers的扩展配置
installer-paths 里写错变量会怎样
installer-paths 的路径值支持 {$name}、{$vendor}、{$type} 这几个变量,但它们不是 PHP 变量,而是 Composer installer 的占位符语法。写错或拼错不会报错,只会原样创建目录名。
比如误写成 "wp-content/plugins/{name}/"(少一个 $),结果就是真建一个叫 {name} 的子目录,而不是替换成包名。
- 必须严格使用
{$name},不是$name、{name}或{{name}} -
{$vendor}和{$name}组合时注意斜杠方向,Windows 下也用正斜杠(/),Composer 会自动适配 - 路径末尾建议带斜杠,如
"extensions/{$name}/",否则可能和文件名连在一起(如extensions/myextMyClass.php) - 路径不能以
../开头,Composer 会拒绝解析,防止越界写入
type 不匹配时的 fallback 行为
如果一个包的 type 没被任何已安装的 installer 支持,Composer 默认行为是无视 installer-paths,老老实实扔进 vendor/ —— 不警告、不报错、不提示,静默降级。
这意味着你很难一眼发现配置失效。最容易被忽略的点是:同一个包在不同版本可能改了 type,或者作者删掉了 type 字段。
- 检查方式:进入
vendor/vendor/name/composer.json,看type字段值是否和你installer-paths里写的type:xxx完全一致(包括大小写) - 临时调试:删掉
vendor/和composer.lock,加-vvv参数重跑composer install,观察日志里有没有Using custom installer for xxx这类输出 - 不要依赖 Packagist 页面显示的 type —— 它可能缓存,以实际下载下来的
composer.json为准











