Laravel 8.x パッケージ開発

イントロダクション

パッケージは、Laravelに機能を追加するための主要な方法です。パッケージは、Carbonのような日付を処理するための優れた方法から、SpatieのLaravel Media LibraryのようなEloquentモデルにファイルを関連付けることができるパッケージまであります。

パッケージにはさまざまな種類があります。一部のパッケージはスタンドアロンです。つまり、どのPHPフレームワークでも機能します。CarbonとPHPUnitは、スタンドアロンパッケージの例です。これらのパッケージはいずれも、composer.jsonファイルでリクエストすることにより、Laravelで使用できます。

逆に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__.'/../config/courier.php' => config_path('courier.php'),
    ]);
}

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

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

Note: 設定ファイルでクロージャを定義しないでください。ユーザーがconfig:cache Artisanコマンドを実行すると、正しくシリアル化できません。

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

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

mergeConfigFromメソッドは、パッケージの設定ファイルへのパスを最初の引数に取り、アプリケーションの設定ファイルのコピーの名前を2番目の引数に取ります。

/**
 * 全アプリケーションサービスの登録
 *
 * @return void
 */
public function register()
        __DIR__.'/../config/courier.php', 'courier'
    $this->mergeConfigFrom(
        __DIR__.'/../config/courier.php', 'courier'
    );
}

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

ルート

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

/**
 * 全パッケージサービスの初期起動
 *
 * @return void
 */
public function boot()
{
    $this->loadRoutesFrom(__DIR__.'/../routes/web.php');
}

マイグレーション

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

/**
 * 全パッケージサービスの初期起動
 *
 * @return void
 */
public function boot()
{
    $this->loadMigrationsFrom(__DIR__.'/../database/migrations');
}

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

言語ファイル

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

/**
 * 全パッケージサービスの初期起動処理
 *
 * @return void
 */
public function boot()
{
    $this->loadTranslationsFrom(__DIR__.'/../resources/lang', '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__.'/../resources/lang', 'courier');

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

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

ビュー

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

/**
 * 全パッケージサービスの初期起動処理
 *
 * @return void
 */
public function boot()
{
    $this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');
}

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

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

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

loadViewsFromメソッドを使用すると、Laravelはビューの2つの場所を実際に登録します。アプリケーションのresources/views/vendorディレクトリと指定したディレクトリです。そのため、たとえばcourierパッケージを使用すると、Laravelは最初にカスタムバージョンのビューが開発者によってresources/views/vendor/courierディレクトリに配置されているかどうかを確認します。次に、ビューがカスタマイズされていない場合、LaravelはloadViewsFromの呼び出しで指定したパッケージビューディレクトリを検索します。これにより、パッケージユーザーはパッケージのビューを簡単にカスタマイズ/オーバーライドできます。

ビューのリソース公開

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

/**
 * 全パッケージサービスの初期起動処理
 *
 * @return void
 */
public function boot()
{
    $this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');

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

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

ビューコンポーネント

パッケージにビューコンポーネントが含まれている場合は、loadViewComponentsAsメソッドを使用して、それらのロード方法をLaravelに通知します。loadViewComponentsAsメソッドは、ビューコンポーネントのタグプレフィックスとビューコンポーネントクラス名の配列の2つの引数とります。たとえば、パッケージのプレフィックスがcourierで、AlertおよびButtonビューコンポーネントがある場合、サービスプロバイダのbootメソッドへ以下を追加します。

use Courier\Components\Alert;
use Courier\Components\Button;

/**
 * 全パッケージサービスの初期起動処理
 *
 * @return void
 */
public function boot()
{
    $this->loadViewComponentsAs('courier', [
        Alert::class,
        Button::class,
    ]);
}

ビューコンポーネントをサービスプロバイダ中で登録したら、以下のようにビューの中で参照します。

<x-courier-alert />

<x-courier-button />

無名コンポーネント

パッケージが無名コンポーネントを持っている場合、"views"ディレクトリ(loadViewsFromで指定している場所)のcomponentsディレクトリの中へ設置する必要があります。すると、パッケージのビュー名前空間を先頭に付けたコンポーネント名でレンダーできます。

<x-courier::alert />

コマンド

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

use Courier\Console\Commands\InstallCommand;
use Courier\Console\Commands\NetworkCommand;

/**
 * パッケージサービスの初期処理
 *
 * @return void
 */
public function boot()
{
    if ($this->app->runningInConsole()) {
        $this->commands([
            InstallCommand::class,
            NetworkCommand::class,
        ]);
    }
}

リソース公開アセット

パッケージには、JavaScript、CSS、画像などのアセットが含まれている場合があります。これらのアセットをアプリケーションのpublicディレクトリにリソース公開するには、サービスプロバイダのpublishesメソッドを使用します。この例では、関連するアセットのグループを簡単にリソース公開するために使用できるpublicアセットグループタグも追加します。

/**
 * 全パッケージサービスの初期起動
 *
 * @return void
 */
public function boot()
{
    $this->publishes([
        __DIR__.'/../public' => public_path('vendor/courier'),
    ], 'public');
}

これで、パッケージのユーザーがvendor:publishコマンドを実行すると、アセットが指定するリソース公開場所にコピーされます。通常、ユーザーはパッケージが更新されるたびにアセットを上書きする必要があるため、--forceフラグを使用できます。

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

ファイルグループのリソース公開

パッケージアセットとリソースのグループを個別にリソース公開することを推奨します。たとえば、パッケージのアセットをリソース公開することを強制されることなく、ユーザーがパッケージの設定ファイルをリソース公開できるようにしたい場合もあるでしょう。パッケージのサービスプロバイダからpublishesメソッドを呼び出すときに、それらに「タグ付け」することでこれを行うことができます。例として、タグを使用して、パッケージのサービスプロバイダのbootメソッドで2つのリソース公開グループ(configmigrations)を定義してみましょう。

/**
 * 全パッケージサービスの初期起動処理
 *
 * @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

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュを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)へ移動

その他

?

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