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

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

新規登録して質問してみよう
ただいま回答率
85.37%
DI (Dependence Injection)

DI (Dependence Injection)は、「依存性の注入」という概念を指します。オブジェクト間で依存性のあるコードを外部の設定ファイルから注入するソフトウェアパターン設計思想です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

解決済

2回答

8218閲覧

Laravel コンストラクタインジェクションについて

masa80

総合スコア8

DI (Dependence Injection)

DI (Dependence Injection)は、「依存性の注入」という概念を指します。オブジェクト間で依存性のあるコードを外部の設定ファイルから注入するソフトウェアパターン設計思想です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

1グッド

1クリップ

投稿2018/08/10 02:47

編集2018/08/10 09:07

以下のようなことを実現したいのですが可能でしょうか?
そもそもコンストラクタインジェクションの使い方がおかしい?

親クラスのコンストラクタ

protected $hoge; public function __construct(Hoge $hoge) { $this->hoge = $hoge; $this->hoge->fuga = 'fuga'; // デフォルト値 }

上記の親クラスを継承した子クラスのコンストラクタ。

public function __construct() { parent::__construct(); $this->hoge->fuga = 'piyo'; // 子クラスでデフォルト値を上書きする。 }

上記子クラスのコードは、エラーになります。
parent::__construct();の引数にHogeのインスタンスを渡していないからです。

そのため、子クラスのコンストラクタを以下のようにする必要があります。

public function __construct(Hoge $hoge) { parent::__construct($hoge); $this->hoge->fuga = 'piyo'; // 子クラスでfugaを上書きする。 }

もしくは、親クラスのコンストラクタを以下にするのも解決法かとは思いますが。。

protected $hoge; public function __construct() { $this->hoge = new Hoge(); $this->hoge->fuga = 'fuga'; // デフォルト値 }

親クラスでnewを使うのも微妙ですし、
わざわざ子クラスから渡すのも微妙ですし。。
もっと良い書き方があれば知りたいです。

そもそもコンストラクタインジェクションの使い方がおかしいのでしょうか?
ご教示頂けると有難いです。

退会済みユーザー👍を押しています

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

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

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

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

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

guest

回答2

0

ベストアンサー

コンストラクタインジェクションの使い方

どう使うのが正しいとか、難しいですよね・・・
そこそこlaravelを使っていますが、色々な部分でいまだに「これでいいのかな?もっといい方法があるのでは?」と思うコトが多々あります。

というわけで、「大正解」というものはちょっとわからないので、以下は個人的な見解としてお聞きください。。。


質問のようなことを実際によくしています。
なので可能かどうかについては、「可能」と回答できます。

ただ、DIは「単体テスト」に大きくメリットのあるテクニックですよね。
親クラスの中で単純にnewしてインスタンスを作った場合、親クラスの単体テストが出来なくなるというデメリットになりますので、newする場合は下記のようにすると良いのではないかと思います。

親クラス

php

1protected $hoge; 2public function __construct(Hoge $hoge = null) 3{ 4 $this->hoge = $hoge ? $hoge : new Hoge(); 5 $this->hoge->fuga = 'fuga'; // デフォルト値 6}

実際に私が実装してきたものの場合、
元々「親」にする予定のなかったクラスを、後の機能追加などで似た機能があるため「親」として継承させる、というようなケースが多かったので、親側の修正をしなくて済むよう「子クラスから渡す」方法をとることがほとんどでした。

なので実装のタイミング次第で、
・親クラスでnew
・子クラスから渡す
のどちらにするかは、やりやすい方を選択すればいいのではないかな~ と思っています。

投稿2018/08/10 09:00

mix-peach

総合スコア1910

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

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

masa80

2018/08/13 03:29

>親クラスの中で単純にnewしてインスタンスを作った場合、親クラスの単体テストが出来なくなるというデメリットになりますので、newする場合は下記のようにすると良いのではないかと思います。 なるほど。 ありがとうございます!
guest

0

1案として下記の実装は如何でしょうか?セッターメソッドを作る感じです。
子クラスでコンストラクタインジェクションをしようとすると使えませんが…

(親クラス)

php

1<?php 2 3namespace App\Http\Controllers; 4 5use Illuminate\Http\Request; 6use League\Flysystem\Adapter\AbstractAdapter; 7use App\Test; 8 9Abstract class AbstractTestController extends Controller 10{ 11 protected $testClass; 12 public function __construct(Test $testClass) 13 { 14 $this->testClass = $testClass; 15 } 16 /** 17 * このメソッドでプロパティをオーバーライド可能にする 18 * 19 * @param string $value 20 * @return void 21 */ 22 protected function overrideProperty(string $value) 23 { 24 $this->testClass->property = $value; 25 } 26 /** 27 * 設定されたプロパティをechoする。 28 * 29 * @return void 30 */ 31 public function echoValue() 32 { 33 echo $this->testClass->property."<br>"; 34 } 35}

子クラス

php

1<?php 2 3namespace App\Http\Controllers; 4 5use Illuminate\Http\Request; 6 7class ExtendTestContoller extends AbstractTestController 8{ 9 public function index() 10 { 11 $this->echoValue();//ここはデフォルト値を表示 12 $this->overrideProperty('テスト'); 13 $this->echoValue();//ここはオーバーライドされた値 14 return view('welcome'); 15 } 16}

結果
イメージ説明

投稿2018/08/10 08:58

motuo

総合スコア3027

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問