因为Composer默认只安装到vendor/,要让type=theme包进public/themes,必须自定义Installer插件:supports()严格匹配'theme',getInstallPath()返回相对路径如'public/themes/'.$package->getPrettyName(),且插件需在根项目中声明并清除缓存重装。

composer install 为什么死活不进 public/themes?
因为 composer install 默认只认 vendor/,它根本不会主动去找 public/themes——除非你让某个插件明确告诉它:“遇到 type 是 theme 的包,请往这儿放”。这个“告诉”的动作,不是靠配置项开关,而是靠一个实现了 InstallerInterface 的 PHP 类,在 supports() 返回 true、在 getInstallPath() 返回 public/themes/{$name}。
常见错误现象:
- 插件类已写好、
composer.json里也加了"type": "composer-plugin",但安装后public/themes还是空的 -
composer show能看到插件已加载,supports('theme')也返回true,但文件没复制过去
根本原因往往不在代码逻辑,而在 Composer 的缓存和生命周期:
- 修改插件后必须先运行
composer clear-cache - 删掉整个
vendor/目录和composer.lock - 再执行
composer install——update不会重走安装路径逻辑
如何让 type=theme 的包真正落到 public/themes 下?
关键不是“怎么配”,而是“谁来执行”:必须有一个插件类监听 theme 类型,并接管从解压到复制的全过程。Composer 自身不提供 theme 类型支持,composer/installers 也不默认认它——你得自己写或引入专用 installer。
实操要点:
- 被安装的包(如
acme/my-theme)的composer.json必须显式声明"type": "theme" - 你的插件类中
supports($packageType)必须严格返回$packageType === 'theme'(字符串全等,不是strpos或in_array) -
getInstallPath()返回值必须是相对路径,例如'public/themes/'.$package->getPrettyName(),不能以/开头,也不能含.. - 插件自身必须在根项目的
composer.json中作为require-dev或require声明,且其命名空间需在autoload中可被自动加载
installer-paths 配置为啥没生效?
installer-paths 本身只是个映射表,它不干活;真正干活的是背后那个能识别对应 type 的 installer。如果你写了 "wp-content/plugins/{$name}/": ["type:wordpress-plugin"],但没装 wpackagist/installer,那这条规则就等于白写。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
常见失效场景:
- 漏装对应 installer,比如想用
drupal-module却没composer require drupal-composer/drupal-scaffold(或新版替代方案) - 包的
type和 installer 支持的类型不匹配,例如包设了"type": "my-theme",但composer/installers只认cakephp-plugin等固定值 -
installer-paths写在了extra外层,或者嵌套层级不对,导致 Composer 完全忽略该配置
补救方法:
- 确认已运行
composer require composer/installers(基础通用 installer) - 检查目标包在 Packagist 上公开的
type字段,而不是你本地改的 - 把
installer-paths放进composer.json的extra段顶层,格式为对象而非数组
vendor-dir 改了,autoload.php 就自动适配吗?
会。Composer 生成的 vendor/autoload.php 是动态适配 config.vendor-dir 的,只要你在 composer.json 里设了 "vendor-dir": "lib/vendor",再清空重装,新生成的 autoload 文件就会从 lib/vendor/autoload.php 开始找路径。
但注意:这只是自动加载器层面的适配。其他地方不会自动跟上:
- 你代码里写的
require 'vendor/autoload.php'必须手动改成require 'lib/vendor/autoload.php' -
bin/下的命令行工具(如phpunit)也会生成在新路径下,调用时得用lib/vendor/bin/phpunit - IDE(如 PhpStorm)可能还缓存着旧
vendor路径,需要手动刷新索引或重新指定目录 - 某些插件或脚本如果硬编码了
vendor/,它们会直接崩,这类依赖必须同步检查和修复
最麻烦的从来不是改路径本身,而是所有隐式依赖该路径的地方——autoload、bin、IDE、CI 脚本、甚至某些第三方库的内部检测逻辑。稍有遗漏,就是 Class not found 或命令找不到。

















