设置和使用自定义安装程序
有时,一个包可能需要在安装过程中执行额外操作,例如在默认的vendor库之外安装包。
在这些情况下,你可以考虑创建一个自定义安装程序来处理你的特定逻辑。
Composer 2.1+的自定义安装程序替代方案
Section titled “Composer 2.1+的自定义安装程序替代方案”自 Composer 2.1 起,Composer\InstalledVersions 类有一个getInstalledPackagesByType方法,可让你在运行时确定已安装哪些插件/模块/扩展。
如果您正在构建新的应用程序,强烈建议使用该工具,而不是构建新的自定义安装程序。这样做的好处是将所有供应商代码保留在供应商目录中,并且不需要自定义安装程序代码。
调用自定义安装程序
Section titled “调用自定义安装程序”假设你的项目已经有了针对特定模块的自定义安装程序,那么调用该安装程序只需在你的包文件中定义正确的类型即可。
有关如何创建自定义安装程序的说明,请参见下一章。
每个自定义安装程序都会定义它将识别的类型字符串。一旦被识别,它将完全覆盖默认安装程序,并且只应用其自身的逻辑。
一个示例用例如下:
phpDocumentor 具有需要安装在默认 /vendor 文件夹结构之外的模板。因此,他们选择采用
phpdocumentor-template类型,并创建一个提供 CustomInstaller 的插件,将这些模板发送到正确的文件夹。
这样一个模板包的composer.json示例如下:
{ "name": "phpdocumentor/template-responsive", "type": "phpdocumentor-template", "require": { "phpdocumentor/template-installer-plugin": "*" }}重要提示:为确保在安装模板包时模板安装程序已存在,模板包应依赖插件包。
创建安装程序
Section titled “创建安装程序”自定义安装程序被定义为一个实现了Composer\Installer\InstallerInterface的类,通常在Composer插件中分发。
因此,一个基本的安装程序插件将由三个文件组成:
- 包文件:composer.json
- Plugin 类,例如:
My\Project\Composer\Plugin.php,其中包含一个实现了Composer\Plugin\PluginInterface的类。 - Installer类,例如:
My\Project\Composer\Installer.php,其中包含一个实现了Composer\Installer\InstallerInterface的类。
作曲家. json
Section titled “作曲家. 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类,例如。
Plugin 类
Section titled “Plugin 类”定义Composer插件的类必须实现Composer\Plugin\PluginInterface。然后,它可以在其activate()方法中注册CustomInstaller。
该类可以放在任何位置,并且可以有任何名称,只要它是可自动加载的,并且与包定义中的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); }}自定义安装程序类
Section titled “自定义安装程序类”执行自定义安装的类应该实现Composer\Installer\InstallerInterface(或者扩展另一个实现了该接口的安装程序)。它会定义类型字符串,以便在supports()方法中被将要使用此安装程序的包识别。
注意:请谨慎选择您的类型名称,建议遵循以下格式:
vendor-type。例如:phpdocumentor-template。
InstallerInterface类定义了以下方法(有关确切签名,请参见源代码):
- supports(),在这里,你要测试传递的类型是否与你为本安装程序声明的名称相匹配(参见示例)。
- isInstalled(),用于确定受支持的包是否已安装。
- install(),在这里你可以确定安装时需要执行的操作。
- update(),在这里你要定义当Composer使用update参数调用时所需的行为。
- 卸载(),在这里你可以确定当软件包需要被移除时需要执行的操作。
- 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>文件夹中。