extra字段仅为数据容器,不自动生效,须由插件或脚本主动读取;必须位于composer.json顶层,类型为对象,结构自由,但需避免破折号开头键名、勿嵌套scripts,读取时须做存在性与类型校验。
extra 字段本身不生效,它只是个数据容器;你写进去的任何内容,必须由插件、脚本或工具主动读取,否则就躺在composer.json 里吃灰。
extra 字段写在哪、长什么样
它必须是
的顶层字段,类型为对象(JSON object),结构完全自由:
注意几点:
不是配置项,
才控制 Composer 自身行为(比如
)
键名别用破折号开头(如
),JSON 解析可能失败;推荐小写字母+下划线,如
嵌套对象和数组都合法,适合组织复杂参数
不要在
里塞
—— 那是顶层字段,
不会被自动注册
怎么在自定义脚本里安全读取 extra
你在
里写的命令(比如
),可以通过
拿到根项目的
数据:
常见错误:
Composer 2.9.6
Composer 2.9.6 是 PHP 生态中高效、稳定的依赖管理工具。此版本在性能与兼容性上进一步优化,改进了依赖解析算法,提升大型项目中的安装与更新速度。它支持并行下载任务,显著减少等待时间,并增强了与私有仓库及镜像源的交互稳定性。同时修复了多项命令行交互与内存使用相关的缺陷,确保在复杂依赖关系下依然可靠运行。无论是新项目初始化还是现有系统维护,Composer 2.9.6 都能为开发者提供流畅、精准的依赖管理体验。
下载
直接写
—— 缺少键时会 Notice 或 Warning
在
的包里读取根项目的
——
返回的是当前包(即那个 require 包)的元数据,不是根项目
把
当全局变量用,没做默认值兜底,导致 CI 环境下
直接 fatal
插件中读取 extra 的正确姿势
如果你开发的是
,必须在
方法里读取,并做好防御性检查:
关键点:
不要在构造函数里读
—— 此时
还没传进来
别硬依赖某个 key 存在,所有访问都要有
或
保护
插件的
配置只对当前插件有效,其他插件或脚本不会自动感知
如果插件需支持 Laravel、Drupal 等生态,建议文档里明确写出你读哪个 key,比如
extra 和 config、scripts 的分工边界
三者常被混淆,但职责完全不同:
:影响 Composer 全局行为,比如
、
,所有命令都受其约束
:声明可触发的钩子命令,如
,本身不存数据,只定义“什么时候跑什么”
:纯数据载体,没有语义,就像一个共享内存区 —— 谁读、怎么读、读了干啥,全由你写的插件或脚本决定
最容易被忽略的一点:extra 字段的值,在
期间可能被缓存,如果你改了 extra 但没看到插件响应,先试
再确认逻辑是否真被触发。
composer.json{
"name": "my/project",
"type": "project",
"extra": {
"app-version": "2.1.0",
"build-target": "staging",
"my-plugin-config": {
"timeout": 30,
"skip-validation": false
}
}
}extraconfigprocess-timeout-debugapp_envextrascriptsextra.scriptsscriptspost-install-cmdScriptEventextrause Composer\Script\Event;
public static function postInstall(Event $event)
{
$composer = $event->getComposer();
$extra = $composer->getPackage()->getExtra();
// 安全取值:先判断键是否存在,再校验类型
$buildTarget = $extra['build-target'] ?? 'production';
$config = $extra['my-plugin-config'] ?? [];
if (is_array($config) && isset($config['timeout'])) {
// 启动清理、生成配置等逻辑
}
}$extra['my-plugin-config']['timeout']requireextra$composer->getPackage()extracomposer installtype: composer-pluginactivate()use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
class MyPlugin implements PluginInterface
{
public function activate(Composer $composer, IOInterface $io)
{
$extra = $composer->getPackage()->getExtra();
// 推荐:用唯一前缀避免冲突,比如插件名缩写
$cfg = $extra['myplugin'] ?? [];
$enabled = $cfg['enable'] ?? false;
$logLevel = $cfg['log-level'] ?? 'info';
if ($enabled) {
$io->write("MyPlugin activated, log level: {$logLevel}");
}
}
}extra$composer??isset()extraextra.laravel-stubs-pathconfigvendor-dirprocess-timeoutscriptspost-autoload-dumpextracomposer updatecomposer update --no-cache