Laravel services.jsonのなぞ

これは Laravelリファレンス発売記念、販売促進アドベントカレンダー www.adventar.org の2015年12月17日分です。

今回はLaravelに欠かせないファイル、services.jsonについて紹介します。

services.json

Laravel5.1ではbootstrap/cache配下に作成されます。
Laravel4でも存在しています。

このファイルはHttp\Kernel、またはConsole\Kernelのbootstrappersプロパティで指定されている、
Illuminate\Foundation\Bootstrap\RegisterProvidersクラスの内部で利用する、
Illuminate\Foundation\ProviderRepositoryクラスが作成します。

ファイルがない場合はcompileManifestメソッドが作成をしています。
config/app.phpのprovidersに記述されてサービスプロバイダが、配列でこのメソッドに渡され、
各サービスプロバイダのインスタンスを生成して、遅延読み込みかそうでないか、
whenによるregisterが存在するかどうかなどを調べてservices.jsonに書き込みます。

以降はこのファイルを元にフレームワークへサービスコンテナなどの登録が行われます。
このファイルがない場合はどうなるのでしょうか?

App\Http\Kernelクラスで$bootstrappersプロパティを使って上書きます。
といってもコメントアウトするだけです。

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * @var array
     */
    protected $bootstrappers = [
        'Illuminate\Foundation\Bootstrap\DetectEnvironment',
        'Illuminate\Foundation\Bootstrap\LoadConfiguration',
        'Illuminate\Foundation\Bootstrap\ConfigureLogging',
        'Illuminate\Foundation\Bootstrap\HandleExceptions',
        'Illuminate\Foundation\Bootstrap\RegisterFacades',
        // 'Illuminate\Foundation\Bootstrap\RegisterProviders',
        'Illuminate\Foundation\Bootstrap\BootProviders',
    ];

    // 省略

bootstrappersプロパティ

このプロパティを利用してフレームワークの動作を独自のものに変更することもできます。
例えば.envファイルではなく他のものを利用するように変更したり、
前回紹介したファサードの削除、
設定ファイルをphpの配列ではなく別のものにしたり、ということができます。

services.jsonを利用しないように変更すると、
フレームワークデフォルトの状態のままであれば、グローバルミドルウェア通過時にクラスが解決できずに、
エラーとなります。
ミドルウェアを全てコメントアウトしてもフレームワークが依存しているクラスのインスタンスを生成できずに動作できなくなります。

このservices.jsonフレームワークの最もコアとも言えるファイルというわけです。

気をつけること

フレームワークは常にこのserivces.jsonに記述されているprovidersと、config/app.phpのprovidersの個数を比較しているため、
登録済みのサービスプロバイダの一部を遅延や、そうでないものに変更すると反映されません。
この場合はかならずphp artisan clear-compiledを実行して最新のservices.jsonを作成しましょう。

この動作さえ理解していれば、フレームワークを様々な方法で拡張することができるようになるでしょう!
(あまり実用的ではありません)