自定义安装程序的设置和使用#
概述#
有时,包可能需要在安装期间执行额外的操作,例如在默认的 vendor
库之外安装包。
在这种情况下,您可以考虑创建自定义安装程序来处理您的特定逻辑。
Composer 2.1+ 中自定义安装程序的替代方案#
从 Composer 2.1 开始,Composer\InstalledVersions
类有一个 getInstalledPackagesByType
方法,该方法可以让你在运行时确定哪些插件/模块/扩展已安装。
如果您正在构建一个新的应用程序,强烈建议您使用它而不是构建新的自定义安装程序。这具有将所有供应商代码保留在供应商目录中的优点,并且不需要自定义安装程序代码。
调用自定义安装程序#
假设您的项目已经为特定模块创建了自定义安装程序,那么调用该安装程序只需在您的包文件中定义正确的 类型。
请参阅下一章了解如何创建自定义安装程序的说明。
每个自定义安装程序都会定义它将识别的 类型 字符串。一旦被识别,它将完全覆盖默认的安装程序,并且只应用它自己的逻辑。
一个用例示例是
phpDocumentor 的特性模板需要安装在默认的 /vendor 文件夹结构之外。因此,他们选择采用
phpdocumentor-template
类型 并创建一个插件,该插件提供自定义安装程序将这些模板发送到正确的文件夹。
此类模板包的 composer.json 示例:
{
"name": "phpdocumentor/template-responsive",
"type": "phpdocumentor-template",
"require": {
"phpdocumentor/template-installer-plugin": "*"
}
}
重要提示:为了确保模板安装程序在模板包安装时存在,模板包应该需要插件包。
创建安装程序#
自定义安装程序被定义为一个类,该类实现了 Composer\Installer\InstallerInterface
,通常在 Composer 插件中分发。
因此,一个基本的安装程序插件将由三个文件组成
- 包文件:composer.json
- 插件类,例如:
My\Project\Composer\Plugin.php
,包含一个实现Composer\Plugin\PluginInterface
的类。 - 安装程序类,例如:
My\Project\Composer\Installer.php
,包含一个实现Composer\Installer\InstallerInterface
的类。
composer.json#
包文件与任何其他包文件相同,但具有以下要求
示例
{
"name": "phpdocumentor/template-installer-plugin",
"type": "composer-plugin",
"license": "MIT",
"autoload": {
"psr-0": {"phpDocumentor\\Composer": "src/"}
},
"extra": {
"class": "phpDocumentor\\Composer\\TemplateInstallerPlugin"
},
"require": {
"composer-plugin-api": "^1.0"
},
"require-dev": {
"composer/composer": "^1.3"
}
}
上面的示例在其 require-dev 中有 Composer 本身,这允许您在测试套件中使用 Composer 类,例如。
插件类#
定义 Composer 插件的类必须实现 Composer\Plugin\PluginInterface
。然后它可以在其 activate()
方法中注册自定义安装程序。
该类可以放置在任何位置,并具有任何名称,只要它可自动加载并且与包定义中的 extra.class
元素匹配即可。
示例
<?php
namespace phpDocumentor\Composer;
use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
class TemplateInstallerPlugin implements PluginInterface
{
public function activate(Composer $composer, IOInterface $io)
{
$installer = new TemplateInstaller($io, $composer);
$composer->getInstallationManager()->addInstaller($installer);
}
}
自定义安装程序类#
执行自定义安装的类应该实现 Composer\Installer\InstallerInterface
(或扩展实现该接口的另一个安装程序)。它定义了 类型 字符串,因为将在 supports()
方法中被使用此安装程序的包识别。
注意:请仔细选择您的 类型 名称,建议遵循格式:
vendor-type
。例如:phpdocumentor-template
。
InstallerInterface 类定义了以下方法(有关确切签名,请参阅源代码)
- supports(),在这里您测试传递的 类型 是否与您为此安装程序声明的名称匹配(参见示例)。
- isInstalled(),确定支持的包是否已安装。
- install(),在这里您可以确定安装时需要执行的操作。
- update(),在这里您定义 Composer 使用 update 参数调用时所需的行为。
- uninstall(),在这里您可以确定包需要删除时需要执行的操作。
- getInstallPath(),此方法应返回包将安装到的绝对路径。路径不能以斜杠结尾。
示例
<?php
namespace phpDocumentor\Composer;
use Composer\Package\PackageInterface;
use Composer\Installer\LibraryInstaller;
class TemplateInstaller extends LibraryInstaller
{
/**
* @inheritDoc
*/
public function getInstallPath(PackageInterface $package)
{
$prefix = substr($package->getPrettyName(), 0, 23);
if ('phpdocumentor/template-' !== $prefix) {
throw new \InvalidArgumentException(
'Unable to install template, phpdocumentor templates '
.'should always start their package name with '
.'"phpdocumentor/template-"'
);
}
return 'data/templates/'.substr($package->getPrettyName(), 23);
}
/**
* @inheritDoc
*/
public function supports($packageType)
{
return 'phpdocumentor-template' === $packageType;
}
}
该示例演示了可以扩展 Composer\Installer\LibraryInstaller
类以剥离前缀 (phpdocumentor/template-
) 并使用剩余部分来组装一个完全不同的安装路径。
任何使用此安装程序安装的包都不会安装在
/vendor
中,而是放在/data/templates/<stripped name>
文件夹中。
发现错别字?此文档中有什么错误? 分支并编辑 它!