イントロダクション
パッケージは、Laravelに機能を追加する、一番重要な方法です。パッケージとして、何でも動作させることができます。たとえば、日付ライブラリーであるCarbonや、振る舞い駆動開発(BDD)テストフレームワークのBehatなどです。
もちろん、他の種類のパッケージも存在しています。スタンドアローンで動作するパッケージもあります。動作させるのにLaravelに限らず、どんなフレームワークも必要としません。CarbonもBehatもスタンドアローンパッケージの例です。Laravelと一緒に使用するには、composer.json
ファイルでシンプルに使用を指定します。
その一方で、特にLaravelと一緒に使用されることを意図した別のパッケージも存在しています。以前のバージョンのLaravelでは、こうしたパッケージを「バンドル」と呼んでいました。この種のパッケージは、ルート、コントローラー、ビュー、設定、マイグレーションを持ち、Laravelアプリケーションを補助する目的を持っています。スタンドアローンなパッケージを開発するためには、特別な工程は必要ありませんから、このガイドでは、主にLaravelに特化した、パッケージ開発について説明していきます。
Laravelのパッケージは、全てPackagistと Composerにより配布されます。ですから、これらの素晴らしいPHPパッケージ配布ツールについて学ぶことは、大切です。
パッケージの作成
Laravelの新しいパッケージを作成する、一番簡単な方法は、workbench
Artisanコマンドを使うことです。
最初にapp/config/workbench.php
のオプションをいくつか設定する必要があります。このファイルにはname
とemail
オプションがあります。それらの値は新しいパッケージに対するcomposer.json
ファイルを生成する時に使用されます。値を設定したら、ワークベンチパッケージを構築する準備が整いました!
Workbench Artisanコマンドの実行
php artisan workbench vendor/package --resources
他の製作者の同じ名前のパッケージと、あなたのものを区別するためにベンダー名は使われます。たとえば、私(Taylor
Otwell)が、"Zapper"という名前で新しいパッケージを作成したら、Taylor
というベンダー名、Zapper
というパッケージ名を付けることができます。デフォルトでは曖昧なフレームワークパッケージが生成されます。しかしながら、resources
コマンドによりLaravelに対しmigrations
、views
、config
などのように特定のディレクトリーを指定し、ワークベンチへパッケージを生成するように指定できます。
一度workbench
コマンドを実行すると、Laravelのインストールディレクトリーにworkbench
ディレクトリーが作成されます。次に、パッケージのために作成した、サービスプロバイダー(ServiceProvider
)を登録する必要があります。app/config/app.php
ファイルのproviders
配列に、プロバイダーを登録します。これにより、アプリケーションが開始した時点で、あなたのパッケージを読み込むように指示します。サービスプロバイダーはパッケージ名ServiceProvider
という命名規則です。前記の例でしたら、Taylor\Zapper\ZapperServiceProvider
をproviders
配列に付け加えます。
プロバイダを登録したら、パッケージを開発する準備が整いました! しかし、実際に取り掛かる前に、パッケージ構造と開発の手順を予習しましょう。
注目: もしサービスプロバイダーが見つけられない場合、アプリケーションのルートディレクトリーで、
php artisan dump-autoload
コマンドを実行してください。
パッケージ構造
workbench
コマンドを使えば、Laravelフレームワークの他の要素も、うまく統合したパッケージを準備してくれます。
基本的なパッケージ構造
/src
/Vendor
/Package
PackageServiceProvider.php
/config
/lang
/migrations
/views
/tests
/public
この構造の特徴を説明しましょう。src/Vendor/Package
ディレクトリーが、パッケージ全クラスのホームであり、ServiceProvider
を含んでいます。config
、lang
、migrations
、views
ディレクトリーは名前が示す通り、対応するリソースです。「普通」のアプリケーションのように、パッケージはどんなリソースも持つことができます。
サービスプロバイダー
サービスプロバイダーは、パッケージのシンプルな、ブートストラップクラスです。デフォルトは、boot
とregister
の2つのメソッドで構成されます。このメソッド内で、何でもお好きな準備を行えます。ルートファイルをインクルードする、IoCコンテナの結合を登録する、イベントリスナーを登録するなど、何でもです。
register
メソッドは、サービスプロバイダーが登録された時点で、すぐに呼び出されます。その一方、boot
メソッドは、リクエストがルートされる直前に、一回だけ呼び出されます。ですから、もしサービスプロバイダーの中のアクションが、既に登録されている別のサービスプロバイダーに依存していたり、他のプロバイダーに結びついたサービスをオーバーライドする場合は、boot
メソッドを使用する必要があります。
workbench
コマンドでパッケージを作成すれば、boot
メソッドは以下の1アクションを含んで作成されています。
$this->package('vendor/package');
このメソッドは、あなたのアプリケーションに対し、ビューや設定、その他のリソースをLaravelへどうやて確実にロードすればよいのか、知らせます。ワークベンチの規則に従って準備がされているのでしたら、通常この一行を変更する必要はありません。
デフォルトではパッケージを登録した後、vendor/package
の"package"部分を指定し、リソースにアクセスできます。しかしながら、package
メソッドの第2引数にしてすることで、変更可能です。例をご覧ください。
// カスタム名前空間をpackageメソッドに渡す
$this->package('vendor/package', 'custom-namespace');
// これで、custom-namespaceでパッケージのリソースにアクセスできる
$view = View::make('custom-namespace::foo');
サービスプロバイダークラスの「デフォルト設置場所」はありません。どこにでも好きな場所に置けますが、多分通常はapp
ディレクトリーの中のProviders
名前空間へ組織化し、設置することでしょう。Composerのオートロード機能が認識できる場所であればどこにでも、ファイルを設置することができます。
設定ファイルやビューなど、パッケージのリソースの設置場所を変更する場合は、package
メソッドの第三引数に、リソースのパスを指定してください。
$this->package('vendor/package', null, '/path/to/resources');
遅延プロバイダー
設定やビューなどのリソースを登録しないサービスプロバイダーを書いているのでしたら、そのプロバイダーを「遅延」する選択を選ぶこともできます。遅延サービスプロバイダーは、アプリケーションのIoCコンテナにより、実際にサービスが必要になった時に、ロード、登録されます。リクエストサイクルで、プロバイダーが提供するサービスが必要ない場合、プロバイダーは一切ロードされません
サービスプロバイダーを遅延実行するには、プロバイダーのdefer
プロパティーをtrue
にセットしてください。
protected $defer = true;
次に、Illuminate\Support\ServiceProvider
クラスのprovides
メソッドをオーバーライトし、そのプロバイダーがIoCコンテナに追加した、全結合の配列を返す必要があります。例えば、プロバイダーでpackage.service
とpackage.another-service
をIoCコンテナに登録したら、provides
メソッドは、次のようになります。
public function provides()
{
return array('package.service', 'package.another-service');
}
パッケージの規約
パッケージの設定ファイルやビューなどのリソースを活用するため、一般的に二重のコロンの文法が使用されます。
パッケージからビューを読み込む
return View::make('package::view.name');
パッケージの設定ファイルアイテムを取得する
return Config::get('package::group.option');
注目:もしパッケージがマイグレーションを含んでいるのでしたら、他のパッケージのマイグレーションと名前がかち合うのを避けるため、パッケージ名を先頭に付ける考慮をお願いします。
開発ワークフロー
パッケージを開発する場合、テンプレートなどを簡単に見たり、試したりできるように、アプリケーションの内部で開発できたほうが便利です。そのため、開発を開始するときは、Laravelフレームワークを新しくインストールし、次にworkbench
コマンドでパッケージの構造を生成しましょう。
workbench
コマンドでパッケージを生成した後に、workbench/[ベンダー]/[パッケージ]
ディレクトリーで、git init
を行い、続いてgit pust
でワークベンチを直接git管理できます!この方法は、何度もcomposer update
を繰り返すことで開発が停滞すること無しに、アプリケーション上でパッケージの開発を便利に行えるようにしてくれます。
あなたのパッケージはworkbench
ディレクトリーの中にあるのに、Composerは自動的にあなたのパッケージのファイルをロードするのは不思議に思えることでしょう。workbench
ディレクトリーが存在すると、Laravelはパッケージを賢くスキャンし、アプリケーションがスタートした時点でComposerのオートロードファイルをロードします!
もしパッケージのオートロードファイルを再生成する必要があるときは、php artisan dump-autoload
コマンドを使ってください。このコマンドはルートプロジェクトのオートロードファイルを再生成すると同時に、あなたが作成したワークベンチのものも再生成します。
Artisanオートロードコマンドを実行する
php artisan dump-autoload
パッケージルーティング
前バージョンのLaravelではhandles
オプションで、どのURIにパッケージが対応するのかを指定していました。しかし、Laravel4ではどのURIに対してもパッケージは対応します。パッケージのルートファイルを読み込むためには、サービスプロバイダーのboot
メソッドの中でシンプルにinclude
してください。
サービスプロバイダーからルート定義ファイルインクルードする
public function boot()
{
$this->package('vendor/package');
include __DIR__.'/../../routes.php';
}
注意:パッケージでコントローラーを使用している場合、ファイルをロードできるように、
composer.json
で確実に設定してください。
パッケージ設定
パッケージ設定ファイルにアクセスする
パッケージの中には設定ファイルを必要とするものもあります。それらのファイルは、アプリケーションの典型的な設定ファイルと同じやり方で定義しなくてはなりません。そしてサービスプロバイダーの中でリソースを登録するデフォルトの$this->package
メソッドを使用する時に、通常「二重のコロン(::)」記法を使用してアクセスします。
Config::get('package::file.option');
一つだけのパッケージ設定ファイルにアクセスする
しかし、もしパッケージに設定ファイルが一つしか必要ないのでしたら、そのファイルにconfig.php
と名付けてください。これによりに、ファイル名を指定せずとも、直接オプションにアクセスできます。
Config::get('package::option');
リソースの名前空間を手動で登録する
場合によっては、典型的な$this->package
方法から外れたビューのような、パッケージリソースを登録したい場合もあることでしょう。リソースが規約外の場所に存在している場合、これが必要になります。リソースを手動で登録するには、View
、Lang
、Config
クラスのaddNamespace
メソッドを使用し、リソースを任意に追加できます。
View::addNamespace('package', __DIR__.'/path/to/views');
一度名前空間を登録すれば、名前空間と「二重コロン」記法で、リソースにアクセスできます。
return View::make('package::view.name');
View
、Lang
、Config
クラスのaddNamespace
メソッドの使い方は、全部同じです。
カスケード式設定ファイル
他の開発者があなたのパッケージをインストールすれば、彼らは設定オプションを上書きするでしょう。パッケージのソースコードの値を変えてしまうと、次回パッケージをComposerでアップデートした時に、変更値はオーバーライトされてしまいます。その代わりに、Artisanコマンドconfig:publish
を使ってください。
php artisan config:publish vendor/package
このコマンドを実行すると、アプリケーションの設定ファイルは、
app/config/packages/vendor/packageにコピーされ
、そこで開発者は安全に変更を加えることができます。
注目:開発者は特定の環境に対するパッケージの設定ファイルをapp/config/packages/vendor/package/environmentに作成できます。
パッケージビュー
アプリケーションの中でパッケージを使用する場合、通常パッケージのビューをカスタマイズしたいでしょう。パッケージのビューは、view:publish
Artisanコマンドを使用し、app/views
ディレクトリーへエクスポートできます。
php artisan view:publish vendor/package
このコマンドは、パッケージのビューをapp/views/packages
ディレクトリーへ移動します。そのディレクトリーが存在しない場合、コマンド実行時に作成されます。一度ビューをエクスポートすれば、それらのリンクを調整することができます!エクスポートされたビューは、自動的にパッケージ自身のビューファイルより優先されます。
パッケージマイグレーション
ワークベンチパッケージに対するマイグレーションを生成する
どのパッケージに対しても簡単にマイグレーションを作成し、実行できます。ワークベンチのパッケージでマイグレーションを生成するには、--bench
オプションを使ってください。
php artisan migrate:make create_users_table --bench="vendor/package"
ワークベンチパッケージに対するマイグレーションを実行する
php artisan migrate --bench="vendor/package"
インストールしたパッケージのマイグレーションを実行
Composerを使いvendor
ディレクトリーにインストールし終えたパッケージのマイグレーションを実行するには、--package
オプションを使用して下さい。
php artisan migrate --package="vendor/package"
パッケージアセット
パッケージのアセットをpublicディレクトリーに移動する
パッケージによってはJavascriptやCSS、画像などのアセットを使っています。しかし、vendor
やworkbench
ディレクトリーの中にあるアセットにリンクを張るのは不可能です。そのため、そうしたアセットをアプリケーションのpublic
ディレクトリーへ移動する手段が必要となります。asset:publish
コマンドがこれを行います。
php artisan asset:publish
php artisan asset:publish vendor/package
パッケージがまだworkbench
にある場合は、--bench
オプションを使います。
php artisan asset:publish --bench="vendor/package"
このコマンドはベンダーとパッケージの名前に別にpublic/package
ディレクトリーへアセットを移動します。ですから、パッケージの名前がuserscape/kudos
であれば、public/packages/userscape/kudos
に移動されます。パッケージのビューにアセットへのパスを安全にコードするため、このアセット発行規則を使用してください。
パッケージ公開
パッケージの公開準備が整ったら、Packagistリポジトリーへ送ってください。もしパッケージがLaravel専用なら、laravel
タグをパッケージのcomposer.json
ファイルに追加することを考慮してください。
また、composer.json
ファイルであなたのパッケージが要求されるとき、開発者は安定バージョンを頼ることができますので、タグは親切で役に立ちます。もし、安定バージョンの用意が整っていなければ、コンポーサーのディレクティブでbranch-alias
を使用することを考えてください。
一度パッケージを公開し終えたら、workbench
で生成されたアプリケーション構造の中で、自由に開発を続けることができます。これはパッケージ公開後も開発をやりやすく続けるための素晴らしい方法です。
いくつかの組織は自分たちの開発者のパッケージのため、プライベートリポジトリーをホストすることを選んでいます。もし、これに興味をお持ちであれば、Composerチームにより提供されているSatisプロジェクトをご覧ください。