指令碼#

指令碼是什麼?#

在 Composer 的術語來說,指令碼可以是一個 PHP 的回呼(定義為一個靜態方法)或任何命令列可執行文件命令。 指令碼對於在 Composer 執行程序期間執行一個套件的自訂程式碼或套件特有命令是很有用的。

注意:只有定義在 root 套件 composer.json 中的指令碼會執行。 如果 root 套件的依賴套件指定它自己的指令碼, Composer 不執行那些額外的指令碼。

事件名稱#

Composer 在它的執行程序期間觸發以下具名事件:

Command Events#

Installer Events#

Package Events#

Plugin Events#

注意:Composer 不會在 installupdate 之前做出任何關於你的依賴套件狀態的假設。因此,你不應該在需求 Composer 管理的依賴套件的 pre-update-cmdpre-install-cmd 事件鉤子中指定指令碼。如果你需要在 installupdate 之前執行指令碼,請確保他們已包含在 root 套件中。

定義指令碼#

composer.json 中的 root 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 回呼:

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

Note: During a composer install or update process, a variable named COMPOSER_DEV_MODE will be added to the environment. If the command was run with the --no-dev flag, this variable will be set to 0, otherwise it will be set to 1.

Event classes#

When an event is fired, your PHP callback receives as first argument a Composer\EventDispatcher\Event object. This object has a getName() method that lets you retrieve the event name.

Depending on the script types you will get various event subclasses containing various getters with relevant data and associated objects:

手動執行指令碼#

如果你想要對一個事件手動執行指令碼,語法是:

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

例如 composer run-script post-install-cmd 會執行任何已經被定義的 post-install-cmd 指令碼。

You can also give additional arguments to the script handler by appending -- followed by the handler arguments. e.g. composer run-script post-install-cmd -- --check will pass--check along to the script handler. Those arguments are received as CLI arg by CLI handlers, and can be retrieved as an array via $event->getArguments() by PHP handlers.

撰寫自訂命令#

If you add custom scripts that do not fit one of the predefined event name above, you can either run them with run-script or also run them as native Composer commands. For example the handler defined below is executable by simply running composer test:

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

Note: Before executing scripts, Composer's bin-dir is temporarily pushed on top of the PATH environment variable so that binaries of dependencies are easily accessible. In this example no matter if the phpunit binary is actually in vendor/bin/phpunit or bin/phpunit it will be found and executed.

Referencing scripts#

To enable script re-use and avoid duplicates, you can call a script from another one by prefixing the command name with @:

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

Calling Composer commands#

To call Composer commands, you can use @composer which will automatically resolve to whatever composer.phar is currently being used:

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

One limitation of this is that you can not call multiple composer commands in a row like @composer install && @composer foo. You must split them up in a JSON array of commands.

執行 PHP 指令碼#

To execute PHP scripts, you can use @php which will automatically resolve to whatever php process is currently being used:

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

One limitation of this is that you can not call multiple commands in a row like @php install && @php foo. You must split them up in a JSON array of commands.

發現錯字?在這個文件中有些錯誤?只要 fork 並編輯 它!