Laravel5.1>=、開発時だけに必要なサービスプロバイダー

タグ: Laravel5.1   Laravel5.2   Composer  

LaravelはComposerに乗っています。Composerには本環境に必要なパッケジと、開発環境だけに必要なパッケージを分けて依存指定できるようになっています。installやupdateの現在のデフォルトは開発環境扱いで、両方共にパッケージの依存が解決されます。(Composerは今までどんどん仕様やデフォルトが変更になってきましたが、最近は比較的固定されています。今後も大きな変化は無いでしょう。)

Composerのinstallやupdateで、本環境に必要なパッケージだけを依存解決し、開発環境に必要なパッケージを無視するには、--no-devオプションを付けます。

Composerレベルではこれで良いのですが、Laravel開発によく使用されるIDEヘルパーやデバッグバーなどは、初期処理を担当するクラスのサービスプロバイダーをapp.php設定ファイルのproviders配列に指定することで有効にします。

providers配列に指定されたクラスが属するパッケージがインストールされているかは考慮されません。そのため、こうした開発環境だけに必要なパッケージも、composer.jsonのrequireセクションに書くのが常套手段です。

しかし、やっぱりなんだかいやですよね。ideヘルパーもデバッグバーもdev-requireセクションに指定したいです。そこで、よく利用するのはサービスプロバイダーで開発時のみ必要なパッケージのサービスプロバーダーを自力で追加する方法です。開発環境では環境名が一般的に"local"ですので、その場合だけに追加で登録する方法です。

しかし、有効にするサービスプロバイダーの設定が設定ファルとサービスプロバイダーに別れるのは気持ちよくありません。

そこでapp.php設定ファイルに、dev-providersdev-aliasesを追加し、これをサービスプロバイダーの中で有効にすることにしました。以下はデバッグバーを登録する例です。

    # 開発環境でのみ必要なサービスプロバイダー
    'dev-providers' => [
        Barryvdh\Debugbar\ServiceProvider::class,
    ],

    # 開発環境でのみ必要なクラスエイリアス
    'dev-aliases' => [
        'Debugbar' => Barryvdh\Debugbar\Facade::class,
    ]

これを新しく作成するサービスプロバイダーか、もしくは最初から用意されているAppServiceProviderに以下のコードを追加します。

    public function boot()
    {
        // Add extra service provider when 'local' environment.
        $extraProviders = $this->app->config->get('app.dev-providers');

        if ($this->app->environment() === 'local' && !empty($extraProviders)) {
            foreach ($extraProviders as $providerName) {
                $this->app->register($providerName);
            }
        }

        // Add extra aliases.
        $extraAliases = $this->app->config->get('app.dev-aliases');

        // Applicaton's alias method don't work. So use alias loader.
        $aliasLoader = AliasLoader::getInstance();

        if (!empty($extraAliases)) {
            foreach ($extraAliases as $alias => $className) {
                if ($this->app->environment() === 'local') {
                    $aliasLoader->alias($alias,$className );
                } else {
                    // Register stab class when it is not in local environment.
                    $aliasLoader->alias($alias, MethodCallHandler::class);
                }
            }
        }

開発環境(local)意外の場合に、エイリアスへアサインしているスタブクラスはこんなダミーです。要は、何もさせません。開発環境で入れたデバッグコードなどが有効にならないようにしています。(ただ、デバッグバー自身もlocal以外ではログされた内容をログファイルに書き込むようになっていますが、そうした機能も無効になります。)

<?php

namespace 適当な名前空間;

/**
 * Stab class to assign alias when non local environment.
 *
 * @author Hirohisa Kawase
 */
class MethodCallHandler
{
    private static $instance = null;

    public function __construct()
    {
        self::$instance = $this;
    }
    /**
     * Handle called method by PHP magic method.
     *
     * @param type $name
     * @param type $arguments
     */
    public function __call($name, $arguments)
    {
        return $this;
    }

    /**
     * Handle static called method by PHP magic method.
     *
     * @param type $name
     * @param type $arguments
     */
    public static function __callStatic($name, $arguments)
    {
        if (is_null(self::$instance)) {
            self::$instance = new MethodCallHandler();
        }

        return self::$instance;
    }
}

と、ここまでやったところで、「毎回これを繰り返して指定するのは嫌だ」と思いましたので、パッケージにしました。インストールはComposerです。

composer require hirokws/prodec

そして、app.phpでサービスプロバイダーを追加します。

    'providers' => [
        ....
        'HiroKws\Prodev\ProdevServiceProvider',
    ],

まだ、ベータ扱いです。バージョン0.*にしてあります。シンプルですし、しばらく使い、問題がなければこのままバージョン1へ上げます。