Laravel5.5 LTS 日本語ドキュメント

このリポジトリはPHP Webアプリフレームワークである、LaravelのLTSバージョンである5.5の公式英文ドキュメントを日本語へ翻訳しています。

This project is maintained by okinaka

パッケージ開発

イントロダクション

パッケージはLaravelに機能を追加する一番重要な方法です。パッケージとして何でも動作させることができます。たとえば日付ライブラリーであるCarbonや、振る舞い駆動開発(BDD)テストフレームワークのBehatなどです。

もちろんパッケージには、色々な種類が存在しています。スタンドアローンで動作するパッケージがあります。つまり、どんなPHPフレームワークでも動作します。CarbonもBehatもスタンドアローンパッケージの例です。Laravelと一緒に使用するにはcomposer.jsonファイルでただ使用を指定するだけです。

逆にLaravelと一緒に使用することを意図したパッケージもあります。こうしたパッケージはLaravelアプリケーションを高めることを特に意図したルート、コントローラ、ビュー、設定を持つことでしょう。このガイドはLaravelに特化したパッケージの開発を主に説明します。

ファサード使用の注意

Laravelアプリケーションをプログラムする場合は、契約とファサードのどちらを使用しても、一般的には問題ありません。両方共に基本的に同じレベルのテスタビリティがあるからです。しかし、パッケージを書く場合は、通常すべてのLaravelテストヘルパにアクセスできません。Laravelアプリケーション内で行うように、パッケージでテストを書けるようにするには、Orchestral Testbenchパッケージを使用してください。

パッケージディスカバリー

Laravelアプリケーションのconfig/app.php設定ファイルには、Laravelがロードすべきサービスプロバイダのリストが、providersオプションで定義されています。誰かが皆さんのパッケージをインストールしたら、皆さんのサービスプロバイダをこのリストに含めてもらいたいと思うことでしょう。このリストへユーザー自身がサービスプロバイダを追加することを要求する代わりに、皆さんのパッケージのcomposer.jsonファイルのextraセクションで、プロバイダを定義してください。登録してもらいたいファサードもリストできます。

"extra": {
    "laravel": {
        "providers": [
            "Barryvdh\\Debugbar\\ServiceProvider"
        ],
        "aliases": {
            "Debugbar": "Barryvdh\\Debugbar\\Facade"
        }
    }
},

ディスカバリー用にパッケージを設定したら、Laravelはサービスプロバイダとファサードをインストール時に自動的に登録します。皆さんのパッケージユーザーに、便利なインストール体験をもたらします。

パッケージディスカバリーの不使用

パッケージを利用する場合に、パッケージディスカバリーを使用したくない場合は、アプリケーションのcomposer.jsonファイルのextraセクションに、使用しないパッケージをリストしてください。

"extra": {
    "laravel": {
        "dont-discover": [
            "barryvdh/laravel-debugbar"
        ]
    }
},

全パッケージに対してディスカバリーを使用しない場合は、アプリケーションのdont-discoverディレクティブに、*文字を指定してください。

"extra": {
    "laravel": {
        "dont-discover": [
            "*"
        ]
    }
},

サービスプロバイダ

サービスプロバイダはパッケージとLaravelを結びつけるところです。サービスプロバイダは何かをLaravelのサービスコンテナと結合し、ビューや設定、言語ファイルのようなリソースをどこからロードするかをLaravelに知らせる責務を持っています。

サービスプロバイダはIlluminate\Support\ServiceProviderクラスを拡張し、registerbootの2メソッドを含んでいます。ベースのServiceProviderクラスは、illuminate/support Composerパッケージにあります。 サービスプロバイダの構造と目的について詳細を知りたければ、ドキュメントを調べてください。

リソース

設定

通常、パッケージの設定ファイルをアプリケーション自身のconfigディレクトリへ公開する必要が起きます。これにより、ユーザーが皆さんのパッケージのデフォルト設定オプションを簡単にオーバーライドできるようになります。設定ファイルを公開するには、サービスプロバイダのbootメソッドで、publishesメソッドを呼び出してください。

/**
 * サービス初期処理登録後の処理
 *
 * @return void
 */
public function boot()
{
    $this->publishes([
        __DIR__.'/path/to/config/courier.php' => config_path('courier.php'),
    ]);
}

これで、皆さんのパッケージのユーザーが、Laravelのvendor:publishコマンドを実行すると、特定の公開場所へファイルがコピーされます。もちろん、設定が公開されても、他の設定ファイルと同様に値にアクセスできます。

$value = config('courier.option');

{note} 設定ファイル中でクロージャを定義してはいけません。パッケージ使用者がconfig:cache Artisanコマンドを使用している場合に、正しくシリアライズできません。

デフォルトパッケージ設定

もしくは、アプリケーションへ公開したコピーと、自身のパッケージの設定ファイルをマージすることもできます。これにより、ユーザーは公開された設定のコピーの中で、実際にオーバーライドしたいオプションのみを定義すればよくなります。設定をマージする場合は、サービスプロバイダのregisterメソッドの中で、mergeConfigFromメソッドを使用します。

/**
 * コンテナ結合の登録
 *
 * @return void
 */
public function register()
{
    $this->mergeConfigFrom(
        __DIR__.'/path/to/config/courier.php', 'courier'
    );
}

{note} このメソッドは設定配列の一次レベルのみマージします。パッケージのユーザーが部分的に多次元の設定配列を定義すると、マージされずに欠落するオプションが発生します。

ルート

パッケージにルートを含めている場合は、loadRoutesFromメソッドでロードします。このメソッドは自動的にアプリケーションのルートがキャッシュされているかを判定し、すでにキャッシュ済みの場合はロードしません。

/**
 * サービス初期処理登録後の処理
 *
 * @return void
 */
public function boot()
{
    $this->loadRoutesFrom(__DIR__.'/routes.php');
}

マイグレーション

もしパッケージがデータベースマイグレーションを含んでいる場合、loadMigrationsFromメソッドを使用し、Laravelへどのようにロードするのかを知らせます。loadMigrationsFromメソッドは引数を一つ取り、パッケージのマイグレーションのパスです。

/**
 * サービス初期処理登録後の処理
 *
 * @return void
 */
public function boot()
{
    $this->loadMigrationsFrom(__DIR__.'/path/to/migrations');
}

パッケージのマイグレーションが登録されると、php artisan migrateコマンド実行時に、自動的にパッケージのマイグレーションも行われます。アプリケーションのdatabase/migrationsディレクトリへ公開する必要はありません。

言語ファイル

パッケージが言語ファイルを含む場合、loadTranslationsFromメソッドを使用し、Laravelへどのようにロードするのかを伝えてください。たとえば、パッケージの名前がcourierの場合、以下のコードをサービスプロバイダのbootメソッドに追加します。

/**
 * サービス初期処理登録後の処理
 *
 * @return void
 */
public function boot()
{
    $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
}

パッケージの翻訳は、package::file.line規約を使い参照します。ですから、courierパッケージのmessagesファイル中の、welcome行をロードするには、次のようになります。

echo trans('courier::messages.welcome');

翻訳の公開

パッケージの翻訳をアプリケーションのresources/lang/vendorディレクトリへ公開したい場合は、サービスプロバイダのpublishesメソッドを使用します。publishesメソッドはパッケージパスと公開したい場所の配列を引数に取ります。たとえば、courierパッケージの言語ファイルを公開する場合は、次のようになります。

/**
 * サービス初期処理登録後の処理
 *
 * @return void
 */
public function boot()
{
    $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');

    $this->publishes([
        __DIR__.'/path/to/translations' => resource_path('lang/vendor/courier'),
    ]);
}

これで、皆さんのパッケージのユーザーが、Laravelのvendor:publish Artisanコマンドを実行すると、パッケージの翻訳は指定された公開場所で公開されます。

ビュー

パッケージのビューをLaravelへ登録するには、ビューがどこにあるのかをLaravelに知らせる必要があります。そのために、サービスプロバイダのloadViewsFromメソッドを使用してください。loadViewsFromメソッドは2つの引数を取ります。ビューテンプレートへのパスと、パッケージの名前です。たとえば、パッケージ名がcourierであれば、以下の行をサービスプロバイダのbootメソッドに追加してください。

/**
 * サービス初期処理登録後の処理
 *
 * @return void
 */
public function boot()
{
    $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}

パッケージのビューは、package::view記法を使い参照します。そのため、ビューのパスを登録し終えたあとで、courierパッケージのadminビューをロードする場合は、次のようになります。

Route::get('admin', function () {
    return view('courier::admin');
});

パッケージビューのオーバーライド

loadViewsFromメソッドを使用する場合、Laravelはビューの2つの場所を実際には登録します。一つはアプリケーションのresources/views/vendorディレクトリで、もう一つは皆さんが指定したディレクトリです。では、courierの例を使って確認しましょう。Laravelは最初にresources/views/vendor/courierの中に、カスタムバージョンのビューが開発者により用意されていないかチェックします。カスタムビューが用意されていなければ、次にloadViewsFromの呼び出しで指定した、パッケージビューディレクトリを探します。この仕組みのおかげで、パッケージのビューがエンドユーザーにより簡単にカスタマイズ/オーバーライドできるようになっています。

ビューの公開

パッケージのビューをresources/views/vendorディレクトリで公開したい場合は、サービスプロバイダのpublishesメソッドを使ってください。publishesメソッドはパッケージのビューパスと、公開場所の配列を引数に取ります。

/**
 * サービス初期処理登録後の処理
 *
 * @return void
 */
public function boot()
{
    $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');

    $this->publishes([
        __DIR__.'/path/to/views' => resource_path('views/vendor/courier'),
    ]);
}

これで皆さんのパッケージのユーザーが、Laravelのvendor::publish Artisanコマンドを実行すると、パッケージのビューは指定された公開場所へコピーされます。

コマンド

パッケージのArtisanコマンドをLaravelへ登録するには、commandsメソッドを使います。このメソッドは、コマンドクラス名の配列を引数に取ります。コマンドを登録したら、Artisan CLIを使い、実行できます。

/**
 * アプリケーションサービスの初期処理
 *
 * @return void
 */
public function boot()
{
    if ($this->app->runningInConsole()) {
        $this->commands([
            FooCommand::class,
            BarCommand::class,
        ]);
    }
}

公開アセット

パッケージにはJavaScriptやCSS、画像などのアセットを含むと思います。こうしたアセットをpublicディレクトリへ公開するには、サービスプロバイダのpublishesメソッドを使用してください。次の例では、関連するアセットをまとめて公開するためにpublicアセットグループタグも追加指定しています。

/**
 * サービス初期処理登録後の処理
 *
 * @return void
 */
public function boot()
{
    $this->publishes([
        __DIR__.'/path/to/assets' => public_path('vendor/courier'),
    ], 'public');
}

これで、皆さんのパッケージのユーザーが、vendor:publishコマンドを実行した時に、アセットは指定した公開場所へコピーされます。通常、パッケージが更新されるごとに、アセットをオーバーライトする必要がありますので、--forceフラグと一緒に使用します。

php artisan vendor:publish --tag=public --force

ファイルグループの公開

アセットとリソースのパッケージグループを別々に公開したいこともあるでしょう。たとえば、パッケージのアセットの公開を強要せずに、設定ファイルを公開したい場合です。パッケージのサービスプロバイダで呼び出す、publishesメソッド実行時の「タグ指定」で行えます。例として、パッケージのサービスプロバイダのbootメソッドで、2つの公開グループを定義してみましょう。

/**
 * サービス初期処理登録後の処理
 *
 * @return void
 */
public function boot()
{
    $this->publishes([
        __DIR__.'/../config/package.php' => config_path('package.php')
    ], 'config');

    $this->publishes([
        __DIR__.'/../database/migrations/' => database_path('migrations')
    ], 'migrations');
}

これでユーザーは、vendor::publish Artisanコマンドを使用するときにタグ名を指定することで、グループを別々に公開できます。

php artisan vendor:publish --tag=config