脚本#

什么是 script ?#

script 被定义在 composer.json 里,可以是 PHP 类静态方法,也可以是可执行的命令行调用。script 是用来 Composer 执行时执行扩展包里的自定义代码,或者扩展包专属的命令行。

注:只有项目里的 composer.json 会被执行,很多时候我们的项目会依赖于多个扩展,这些扩展里的里 composer.json 配置的 script 将不会被执行。


译者注:Laravel 中利用 Composer 的 Script 来执行安装完后的动作,请见代码 https://github.com/laravel/laravel/blob/master/composer.json#L40-L51

事件名称#

Composer 在执行的过程中会触发这些事件,你可以通过监控这些事件来控制 scirpt 的执行顺序。

命令事件#

安装器事件#

扩展包事件#

插件事件#

请注意:在 install 或者update 前,Composer 对你的依赖是一无所知的,所以你不应该在 pre-update-cmd 或者 pre-install-cmd 事件中使用任何第三方依赖的命令。如果你不得不这么做,你可以在你的项目里编写逻辑,然后在 installupdate 命令触发时调用你自己的命令。

定义 scripts#

我们需要在项目的 composer.json 定义一个叫 "scripts" 的选项,在此选项里,设置事件名称和对应的要执行的命令或脚本。命令和脚本的值可以是字符串的名称,也可以是数组(单个或者多个)。

对于每一个事件:

例子:

{
    "scripts": {
        "post-update-cmd": "MyVendor\\MyClass::postUpdate",
        "post-package-install": [
            "MyVendor\\MyClass::postPackageInstall"
        ],
        "post-install-cmd": [
            "MyVendor\\MyClass::warmCache",
            "phpunit -c app/"
        ],
        "post-autoload-dump": [
            "MyVendor\\MyClass::postAutoloadDump"
        ],
        "post-create-project-cmd": [
            "php -r \"copy('config/local-example.php', 'config/local.php');\""
        ]
    }
}

照着上面的定义,我们来编写  MyVendor\MyClass 类,此类的作用是来执行这些回调(注意都是静态方法):

<?php

namespace MyVendor;

use Composer\Script\Event;
use Composer\Installer\PackageEvent;

class MyClass
{
    public static function postUpdate(Event $event)
    {
        $composer = $event->getComposer();
        // do stuff
    }

    public static function postAutoloadDump(Event $event)
    {
        $vendorDir = $event->getComposer()->getConfig()->get('vendor-dir');
        require $vendorDir . '/autoload.php';

        some_function_from_an_autoloaded_file();
    }

    public static function postPackageInstall(PackageEvent $event)
    {
        $installedPackage = $event->getOperation()->getPackage();
        // do stuff
    }

    public static function warmCache(Event $event)
    {
        // make cache toasty
    }
}

请注意:在 Composer 的 installupdate 过程时,环境变量 COMPOSER_DEV_MODE 会被设置,此值来自于执行命令时的 --no-dev 参数,如果设置了为 0,每调用的情况下为 1。

事件类#

当事件被触发时,PHP 的回调代码中会接收到 Composer\EventDispatcher\Event 对象。此对象会有一个 getName() 方法来让你获取到事件的名称。

取决于 script 类型 你会获取到不同的类对象以及各类型对象包含的变量:

手动执行 scripts#

如果你想要手动执行一个事件对应的 scripts ,语法如下:

composer run-script [--dev] [--no-dev] script

例如 composer run-script post-install-cmd 会运行 post-install-cmd 对应的 scripts

你可以使用 -- 来给 scripts 传参,例如 composer run-script post-install-cmd -- --check ,scripts 是命令的情况下,会如正常传参那样接收到 --check 参数,而使用 PHP 脚本的情况下,你可以使用 $event->getArguments() 来获取到相同的传参。

编写自定义命令#

如果你的自定义 scripts 逻辑与所有事件名称都不匹配的话,你也可以自定义自己的 Composer 命令。如下面的定义允许你新增 composer test 命令:

{
    "scripts": {
        "test": "phpunit"
    }
}

这种模式与 run-script 命令一样可以接收参数,如: composer test -- --filter <pattern> 会将参数 --filter <pattern> 传到 phpunit 脚本中。

注意:在执行脚本前,你需要知道,按照一般情况下的配置 Composer 的 bin 目录会放到系统 PATH 前面,所以以上命令 phpunit 无论是在 vendor/bin/phpunit 或者在 bin/phpunit 中,都能够被执行到。

引用脚本#

为了重新使用脚本以及避免重复启用脚本,可以通过在命令前面加上一个  @ 来调用另外一个脚本:

{
    "scripts": {
        "test": [
            "@clearCache",
            "phpunit"
        ],
        "clearCache": "rm -rf cache/*"
    }
}

调用 Composer 命令#

要调用 Composer 命令,可以使用 @composer  ,它会自动解析到当前正在使用的 composer.phar 上面:

{
    "scripts": {
        "test": [
            "@composer install",
            "phpunit"
        ]
    }
}

这样做的一个限制是,你不能像 @composer install && @composer foo 这样在一行调用多个 composer 命令。你必须把他们分隔成一个 JSON 命令数组。

执行 PHP 脚本#

要执行 PHP 脚本,您可以使用 @php 它将自动解析为当前正在使用的 PHP 进程:

{
    "scripts": {
        "test": [
            "@php script.php",
            "phpunit"
        ]
    }
}

这样做的局限是您不能像  @php install && @php foo 这样调用多个命令。您必须将它们拆分为 JSON 命令数组。

自定义说明#

您可以在 composer.json 文件中使用以下内容来设置自定义脚本描述:

{
    "scripts-descriptions": {
        "test": "Run all tests!"
    }
}

注意:您只能设置自定义命令的自定义描述.

发现了一个错字?文档中有问题吗? 只需要 fork并编辑 它!