質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

Q&A

解決済

1回答

1830閲覧

Laravelのバッチのコンストラクタでinterfaceのインジェクションを行いたい

eito_t

総合スコア1

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

0グッド

0クリップ

投稿2021/05/26 10:47

前提・実現したいこと

複数種類のxmlファイルを読み込み、それぞれに対応したテーブルに格納するバッチをLaravelで実装しています。

各xmlの構成はバラバラですが、基本的な処理の流れは以下の通りです。
1.xmlを読み込む

2.解析と整形

3.テーブルにinsert
そのため1つのinterfaceファイルに対して、それをimplementsした各xmlファイル用の実装ファイルを用意し
Commandをextendsした各xmlファイル用のバッチのコンストラクタでinterfaceを引数に取ってインジェクションしたいと考えていますが、以下のエラーが発生するため実現できておりません。
小規模なプロジェクトですのでinterfaceではなく抽象クラスをextendsし、コンストラクタではこのクラスをインジェクションするという実装でも要件は満たせるのですが、せっかくなのでLaravelでよく見る実装で実現できればと思い質問させていただきました。

発生している問題・エラーメッセージ

Illuminate\Contracts\Container\BindingResolutionException : Target [App\Repositories\xxxx\Interfaceのクラス名] is not instantiable while building [App\Console\Commands\xxxx\バッチのクラス名].

該当のソースコード

php

1// interface 2namespace App\Repositories\xxxx; 3interface InterfaceA 4{ 5 public function aaa(); 6} 7 8// interfaceの実装 9namespace App\Repositories\xxxx; 10class ImplementsA implements InterfaceA 11{ 12 public function aaa(){} 13} 14 15// バッチ 16namespace App\Console\Commands\xxxx; 17class BatchA extends Command 18{ 19 private $obj; 20 public function __construct(InterfaceA $param) 21 { 22 $this->obj = $param; 23 } 24 public function handle() 25 { 26 $this->obj->aaa(); 27 } 28}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

インターフェイスをタイプヒントに指定した時にどの実装クラスのインスタンスを生成するかについて、紐付けを記述する必要があります。
上記のサンプルコードで言うと、「InterfaceAクラスがタイプヒントに指定された際にはImplementsAクラスのインスタンスを生成する」と指定してあげる必要があるということになります。

どこにその紐付けの記述をするかというと、
詳しくはLaravelドキュメントに記載があるのでそちらを参考にしていただければと思いますが、ServiceProviderクラスを作成して定義 or すでに用意されているAppServiceProviderクラス内に定義します。

具体的には、

app/Providers/AppServiceProvider.php ...(中略) public function register() { $this->app->bind( (インターフェイス), (実装クラス) ); } ...(中略)

のように紐付け(ドキュメントや書籍では「バインド」、「結合」など呼ばれています)を記述すると、今回の目的であるコンストラクタインジェクションができるようになります。

これはLaravelのサービスコンテナという機能を用いたもので、
詳しくはドキュメントや、『PHPフレームワーク Laravel Webアプリケーション開発』という書籍にも解説が記載されていますので、ぜひご参照ください。

web検索でも「Laravel サービスコンテナ」と調べると、色々出てくると思います。

投稿2021/05/26 13:47

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

eito_t

2021/05/27 23:45

ありがとうございます。 解決しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問