Laravel 5.3 パッケージ開発

イントロダクション

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

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

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

ファサード使用の注意

Laravelアプリケーションをプログラムする場合は、契約ファサードのどちらを使用しても、一般的には問題ありません。両方共に基本的に同じレベルのテスタビリティがあるからです。しかし、パッケージを書く場合は、ファサードの代わりに、契約を使用してください。パッケージでは、Laravelのテストヘルパの全てへアクセスができないためです。ファサードをモックするよりは、契約をモックしたり、スタブするほうが簡単です。

サービスプロバイダ

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

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

ルーティング

パッケージのルートを定義するには、パッケージのサービスプロバイダのbootメソッドからルートファイルパスをloadRoutesFromで指定します。ルートファイルの中から、典型的なLaravelアプリケーションと同様に、Illuminate\Support\Facades\Routeファサードを使い、ルートを登録します。

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

リソース

設定

通常、パッケージの設定ファイルをアプリケーション自身の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: このメソッドは設定配列の一次レベルのみマージします。パッケージのユーザが部分的に多次元の設定配列を定義すると、マージされずに欠落するオプションが発生します。

マイグレーション

もしパッケージがデータベースマイグレーションを含んでいる場合、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

ドキュメント章別ページ

開発環境
ビューとテンプレート
Artisanコンソール
公式パッケージ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

バージョン

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる