4

Pimple と動的コンストラクター インジェクションについて質問があります。

MVC フレームワークがあり、画像のアップロードのようなことをしたいとします。それを行うセミDIの方法は次のようになります。

class ImageUploadController
{
    public function upload()
    {
         $targetImage = new Image(1920, 1080, 75, 'jpg', 'save/path');
         $imageSaver = new JPEGImageSaver($targetImage);
         $imageUploader = new ImageUploader($imageSaver);
         $imageUploader->upload('myUploadfield');
    }
}

基本的Imageには、作成して保存したい画像のプロパティの単純なコンテナーです。、、およびオブジェクトのプロパティと、アップロードされた一時画像のプロパティをJPEGImageSaver使用して、アップロードされた画像の新しい安全なバージョンを保存します。とのインターフェイスを使用して、アップロードされた画像を安全に保存します。imagecreatefromjpeg()imagecopyresized()imagejpeg()ImageImageUploaderJPEGImageSaver

問題は、コントローラーと密接に結合された 3 つのクラスがあることです。これを回避しようとした方法は、Pimple を使用してから Pimple をコントローラーに渡すことです。

class ImageUploadController
{
    public function upload()
    {
         $targetImage = $this->app['Image'];
         $targetImage->setWidth(1920);
         $targetImage->setHeight(1080);
         $targetImage->setQuality(75);
         $targetImage->setExtension('jpg');
         $targetImage->setSavePath('save/path');


         $imageSaver = $this->app['JPEGImageSaver'];
         $imageSaver->setTargetImage($targetImage);

         $imageUploader = $this->app['ImageUploader'];
         $imageUploader->setImageSaver($imageSaver);
         $imageUploader->upload('myUploadField');
    }
}

しかし、ご覧のとおり、コントローラーに依存関係を注入するために Pimple を使用すると、以前よりも使用が複雑になりました。主な問題は、リクエスト中にオブジェクトのコンストラクター値を設定する方法が Pimple にないため、Imageオブジェクトのセッターが多数必要になることです。

この問題の一般的な解決策はありますか? コンストラクター引数を渡すことができる解決コンテナーに Pimple をラップすることを考えましたが、それに関する問題は、IDE がインテリセンシングを通じてさまざまなオブジェクトを構築する方法を示していないことです。$this->app['something']また、コントローラーがどれだけテスト可能になったかについても少し疑わしいです。

コントローラはテスト可能である必要さえありますか? Imageもしそうなら、そのオブジェクトを値オブジェクトと見なすことができますか?

何かご意見は?

4

1 に答える 1

1

Pimple は、値またはサービスを格納するコンテナーです。アプリケーションは、セッション オブジェクトなどのサービスを取得するように Pimple に要求します。

画像クラスがアプリケーション全体で正確な定義で使用されている場合、

<?php

$targetImage = new Image(1920, 1080, 75, 'jpg', 'save/path');

次に、この定義を保存するように Pimpl に依頼できます。

<?php
// define image service
$container['image'] = function ($c) {
    return new Image(1920, 1080, 75, 'jpg', 'save/path');
};

アプリケーションに異なる画像サイズがある場合は、次のようにすることができます。

<?php
// define image service
$container['bigImage'] = function ($c) {
    return new Image(1920, 1080, 75, 'jpg', 'save/path');
};

$container['smallImage'] = function ($c) {
    return new Image(200, 200, 75, 'jpg', 'save/path');
};

さらに進んで、Image クラスのパラメーターを保存し、それらを再利用することができます。

<?php

$container['imageParams'] = [
   'width' => 1920,
   'height' => 1080,
   'type' => 'jpg',
   'quality' => 75
];

// define image service
$container['image'] = function ($c) {
    $image = $c['imageParams'];
    return new Image($image['width'],
                     $image['height'],
                     $image['quality'],
                     $image['type'],
                     'save/path'
    );
};

現在、Pimple では、サービスの取得中にパラメーターを渡すことはできません。

<?php

$this->app['image'](1920, 1080, 75, 'jpg', 'save/path');

この機能を実装するには、Pimple を拡張する必要があります。

ただし、コントローラ クラスにファクトリ メソッドを作成して、Pimple に格納されている画像パラメータを変更し、イメージ サービスを呼び出して特定のパラメータで画像オブジェクトを作成し、格納されているパラメータを元の値に戻すことができます。

<?php

class ImageUploadController {

  protected function imageFactory($width, $height, $type, $quality) {
     // Store original parameters
     $origin = $this->app['imageParams'];

     // Override the original parameters
     $this->app['imageParams']['width'] = $width;
     $this->app['imageParams']['height'] = $height;
     $this->app['imageParams']['quality'] = $quality;
     $this->app['imageParams']['type'] = $type;

     // Get image class
     $image = $this->app['image'];

     // Rest image parameters
     $this->app['imageParams'] = $origin;

     return $image;
  }

  public function upload()
  {
     $targetImage = $this->imageFactory(1920, 1080, 75, 'jpg');

  }
}
于 2015-01-21T02:03:36.747 に答える