SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

人気のPHPフレームワークLaravelを習得しよう

Laravelにおけるサービスコンテナを理解しよう

人気のPHPフレームワークLaravelを習得しよう 第6回

  • X ポスト
  • このエントリーをはてなブックマークに追加

Laravelのサービスプロバイダ

 前節で紹介したサービスコンテナの働きには少し問題があります。この節では、その確認とそれを解決する仕組みとして、サービスプロバイダを紹介します。

コンストラクタの引数があるクラスのインスタンスの取得

 前節で例に挙げたBookクラスやMagazineクラスは、そのクラス自体をnewする際に引数は不要でした。では、インスタンスを生成、つまり、newする際に引数が必要なクラスではどうなるのでしょうか。例えば、リスト10のようなクラスです。

[リスト10]app/Chap6/Note.php
<?php
namespace App\Chap6;

class Note
{
	public function __construct(string $name)
	{
		print("<p>".$name."のNoteクラスのコンストラクタが実行されました。</p>");
	}
}

 このクラスをnewする際は、例えば、以下のように引数を渡す必要があります。

$note = new Note("しんちゃん");

 このNoteクラスのインスタンスをサービスコンテナ経由でもらうとするなら、どうなるでしょうか。もし、resolve()関数を使うならば、以下のように第2引数として連想配列の形で指定することが可能です。

$note = resolve("App\Chap6\Note", ["name"=>"しんちゃん"]);

 第2引数で指定する連想配列は、「引数名=>値」の形で指定します。

サービスプロバイダ

 では、メソッドインジェクションやコンストラクタインジェクションでインスタンスをもらう場合はどうなるでしょうか。例えば、リスト11のnewNote()メソッドのような場合です。

[リスト11]app/Http/Controllers/Chap6Controller.php
<?php
〜省略〜
class Chap6Controller extends Controller
{
	〜省略〜
	public function newNote(Note $note)
	{
		return "<p>newNote()メソッドが実行されました。</p>";
	}
}

 ここで追記したnewNote()メソッドをルーティング登録しましょう。ルーティングパターンは/chap6/newNoteとします。routes/web.phpにリスト12のコードを追記してください。

[リスト12]routes/web.php
Route::get("/chap6/newNote", "Chap6Controller@newNote");

 その後、以下のURLにアクセスしてください。

  • http://localhost/firstlaravel/public/chap6/newNote

 すると、これはエラーとなり、図5の画面となります。

図5: newするときの引数がなくエラーとなった画面
図5:newするときの引数がなくエラーとなった画面

 引数を渡すことができないので、当然です。

 これを解決する仕組みとしてLaravelにはサービスプロバイダというのがあります。サービスプロバイダは、サービスコンテナ経由で取得するインスタンスの生成処理を担うクラスです。

 実際に作成しましょう。リスト13のNoteServiceProviderクラスをapp/Providersディレクトリ内に作成してください。

[リスト13]app/Providers/NoteServiceProvider.php
<?php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Chap6\Note;

class NoteServiceProvider extends ServiceProvider  // (1)
{
	public function register()  // (2)
	{
		$this->app->bind("App\Chap6\Note", function($app) {
			$name = "しんちゃん";
			$note = new Note($name);  // (3)
			return $note;  // (4)
		});
	}
}

 サービスプロバイダは、(1)のようにServiceProviderクラスを継承して作ります。その上で、(2)のregister()メソッド内に以下の構文で該当クラスのインスタンス生成処理を記述します。

[構文]サービスプロバイダクラスのregister()メソッド内の記述
$this->app->bind("該当クラスの完全修飾名", function($app) {
	該当クラスのインスタンスを生成し、リターン
});

 リスト13では、該当クラスがApp\Chap6\Noteですので、このクラスを(3)でnewし、それを(4)でリターンしています。この方式を利用すると、new時に引数を渡すことができるだけでなく、newしたインスタンスに対してさまざまな設定を行ったりした上でリターンすることもできます。

 ただし、このサービスプロバイダはクラスを作成しただけでは利用できません。利用するには、config/app.phpに登録する必要があります。app.phpは連想配列が記述されているだけのファイルです。そのキーprovidersにサービスプロバイダクラスを登録します。リスト14の太字の1行を追記してください。

[リスト14]config/app.php
<?php
return [
	〜省略〜
	'providers' => [
		〜省略〜
		App\Providers\NoteServiceProvider::class,
	],
	〜省略〜
];

 ここまで追記できたら、先のURLにもう一度アクセスしてください。図6の画面が表示され、無事、サービスプロバイダ経由で生成されたNoteインスタンスを、サービスコンテナがメソッドインジェクションで渡してくれているのが確認できます。

図6:サービスプロバイダ経由でインスタンスを取得した画面
図6:サービスプロバイダ経由でインスタンスを取得した画面

まとめ

 今回は、インスタンスの取得を自動化してくれる機能としてLaravelのサービスコンテナとインスタンスの生成処理を担うサービスプロバイダを紹介しました。

 次回は、Laravelアプリでエラーや例外が発生した場合の処理を扱うエラーハンドラを紹介します。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
人気のPHPフレームワークLaravelを習得しよう連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 齊藤 新三(サイトウ シンゾウ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook<個人紹介>WINGSプロジェクト所属のテクニカルライター。Web系製作会社のシステム部門、SI会社を経てフリーランスとして独立。屋号はSarva(サルヴァ)。HAL大阪の非常勤講師を兼務。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/11865 2019/12/26 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング