Composer 自定義安裝程序

2018-09-28 20:24 更新

自定義安裝程序

概要

有時(shí)需要在包的安裝過(guò)程中執(zhí)行其它的動(dòng)作,例如:將它安裝在默認(rèn)的 vendor 以外的其它目錄。

在這些情況下,你可以考慮創(chuàng)建一個(gè)自定義安裝程序來(lái)處理特定的邏輯。

調(diào)用自定義安裝程序

假設(shè)你的項(xiàng)目已經(jīng)有了一個(gè)自定義的安裝模塊,那么如何根據(jù) 安裝類(lèi)型 正確調(diào)用你包文件中的安裝程序就成為了一個(gè)問(wèn)題。

參見(jiàn)見(jiàn)下一章,如何通過(guò)指令創(chuàng)建自定義安裝程序。

任何自定義安裝程序都要通過(guò) type 屬性來(lái)識(shí)別。一旦被確認(rèn),它將完全覆蓋默認(rèn)的安裝程序,并執(zhí)行自己的安裝邏輯。

一個(gè)實(shí)際用例:

phpDocumentor 的特殊模板需要安裝在 /vendor 以外的其它目錄中。 因此他們選擇 phpdocumentor-template 安裝類(lèi)型 并為此類(lèi)型創(chuàng)建了一個(gè)插件,以便將他們的模板發(fā)送到正確的目錄中。

在這樣一個(gè)模板包的例子中 composer.json 將使用以下設(shè)置:

{
    "name": "phpdocumentor/template-responsive",
    "type": "phpdocumentor-template",
    "require": {
        "phpdocumentor/template-installer-plugin": "*"
    }
}

重要提示: 為了確保這個(gè)模板安裝程序在安裝模板包之前就已存在,模板包必須寫(xiě)入對(duì)此安裝程序包的依賴(lài)。

創(chuàng)建一個(gè)安裝程序

一個(gè)自定義安裝程序通常是以 Composer 插件的形式存在,并包含有一個(gè)類(lèi),它實(shí)現(xiàn)了 Composer\Installer\InstallerInterface 這個(gè)接口。

一個(gè)基本的安裝程序插件必須由3個(gè)文件組成:

  1. 包文件:composer.json
  2. 插件類(lèi),例如:My\Project\Composer\Plugin.php,其中的類(lèi)必須實(shí)現(xiàn) Composer\Plugin\PluginInterface 接口。
  3. 安裝程序類(lèi),例如:My\Project\Composer\Installer.php,其中的類(lèi)必須實(shí)現(xiàn) Composer\Installer\InstallerInterface 接口。

composer.json

此處的包文件和普通資源包是相同的,但需要滿(mǎn)足以下條件:

  1. type 屬性必須是 composer-plugin。
  2. extra 屬性必須包含 class 元素,它定義了插件類(lèi)的名稱(chēng)(包含命名空間)。如果這個(gè)包有多個(gè)插件類(lèi),可以使用數(shù)組的形式進(jìn)行定義。

實(shí)例:

{
    "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.0"
    }
}

插件類(lèi)

這個(gè)類(lèi)定義了 Composer 的插件,它必須實(shí)現(xiàn) Composer\Plugin\PluginInterface 這個(gè)接口。它可以在 activate() 方法中注冊(cè)自定義安裝程序。

這個(gè)類(lèi)可以被放在任何位置、使用任何名字,只要能夠根據(jù) extra.class 中的定義被自動(dòng)加載即可。

實(shí)例:

<?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);
    }
}

自定義安裝程序類(lèi)

這個(gè)類(lèi)用于執(zhí)行自定義的安裝過(guò)程,它必須實(shí)現(xiàn) Composer\Installer\InstallerInterface 這個(gè)接口(或者繼承了另一個(gè)實(shí)現(xiàn)此接口的安裝程序類(lèi))。它將會(huì)對(duì)安裝類(lèi)型中定義的字符串執(zhí)行 supports() 方法驗(yàn)證,一旦通過(guò)就采用對(duì)應(yīng)的安裝程序。

注意: 請(qǐng)慎重選擇你的 安裝類(lèi)型 名稱(chēng),建議遵循這樣的格式:vendor-type。例如:phpdocumentor-template。

InstallerInterface 類(lèi)定義了以下方法(請(qǐng)查閱源碼以獲得更詳細(xì)的信息):

  • supports() 在這里測(cè)試你發(fā)布的這個(gè)安裝程序名稱(chēng)是否通過(guò) 安裝類(lèi)型 匹配(參見(jiàn)示例)。只有正確匹配的資源包才會(huì)使用此安裝程序進(jìn)行安裝。
  • isInstalled() 確定支持的資源包是否已安裝。
  • install() 這里你可以定義在安裝時(shí)需要執(zhí)行的動(dòng)作。
  • update() 這里你可以定義在更新時(shí)需要執(zhí)行的動(dòng)作。當(dāng) Composer 調(diào)用更新參數(shù)時(shí)這是必須的。
  • uninstall() 這里你可以定義在移除一個(gè)包時(shí)需要執(zhí)行的動(dòng)作。
  • getInstallPath() 這個(gè)方法需要返回一個(gè)資源包將要安裝的位置。相對(duì)于 composer.json 文件的位置。

實(shí)例:

<?php

namespace phpDocumentor\Composer;

use Composer\Package\PackageInterface;
use Composer\Installer\LibraryInstaller;

class TemplateInstaller extends LibraryInstaller
{
    /**
     * {@inheritDoc}
     */
    public function getPackageBasePath(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;
    }
}

這個(gè)例子演示了,簡(jiǎn)單的繼承 Composer\Installer\LibraryInstaller 類(lèi)來(lái)剝離 phpdocumentor/template- 前綴,并用剩余的部分重新組裝了一個(gè)完全不同的安裝路徑。

并非安裝在 /vendor 目錄,任何使用這個(gè)安裝程序的資源包,將被放置在 /data/templates/<stripped name> 目錄中。

以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)