9

私はZF2システムを開発していますし、それは非常によく働いていたが、私は他のコンピュータでのリポジトリのクローンを作成した後、この非推奨エラーが登場している:は非推奨:機能的なシステムでサービスロケータを取得 - ZF2

をあなたがしていますModule \ Controller \ Controllerクラス内からサービスロケータを取得します。 ServiceLocatorAwareInterfaceは廃止され、ServiceLocatorAwareInterializerと共にバージョン3.0で削除されることに注意してください。作成時にすべての依存関係をコンストラクター引数またはセッターを介して受け入れるようにクラスを更新し、ファクトリを使用して注入を実行する必要があります。ライン258

上/home/path/project/vendor/zendframework/zend-mvc/src/Controller/AbstractController.phpにcomposer.json:私が取得するとき

"require": { 
    "php": ">=5.5", 
    "ext-curl": "*", 
    "ext-json": "*", 
    "ext-mbstring": "*", 
    "zendframework/zendframework": "~2.5", 
    "doctrine/doctrine-orm-module": "0.*", 
    "hounddog/doctrine-data-fixture-module": "0.0.*", 
    "imagine/Imagine": "~0.5.0" 

のエラーが表示されます。 (Zendの\ MVC \コントローラ\ AbstractActionControllerを拡張する)私のコントローラでサービス:Zendの\ MVC \コントローラ\ AbstractControllerでZendのコアで

$this->getServiceLocator()->get("Module\Service\Service"); 

は、このようなものです:

ただけで、この前
public function getServiceLocator() 
{ 
    trigger_error(sprintf(
     'You are retrieving the service locator from within the class %s. Please be aware that ' 
     . 'ServiceLocatorAwareInterface is deprecated and will be removed in version 3.0, along ' 
     . 'with the ServiceLocatorAwareInitializer. You will need to update your class to accept ' 
     . 'all dependencies at creation, either via constructor arguments or setters, and use ' 
     . 'a factory to perform the injections.', 
     get_class($this) 
    ), E_USER_DEPRECATED); 

    return $this->serviceLocator; 
} 

public function getServiceLocator() 
{ 
    return $this->serviceLocator; 
} 

私は誰かが私が何をしてきたか知っている、すべてのものを試してみましたか?

+0

それはメッセージの中にあります: '作成時にすべての依存関係を受け入れるようにクラスを更新する必要があります。これはc建設業者の引数やセッターを使って、注入を行うために工場を利用しています。 –

+0

私はこのメッセージをよく理解していませんでした。「あなたのクラスを更新する必要はありますか? –

+0

[PHP非推奨:ZFTool \ Controller \ ModuleControllerクラス内からサービスロケータを取得しています(http://stackoverflow.com/questions/35933113/php-deprecated-you-are-retrieving-the-service -locator-from-the-class-zft) –

答えて

10

何もする必要はありません。まだです。 ZF3にアップグレードすると、コントローラクラスの依存関係の変更方法を変更する必要があります。

ZF2は、サービスロケータとコンストラクタによって2つの依存性注入パターンをサポートしています。 ZF3は "サービスロケーション別"を削除し、 "コンストラクター"を必要とします。これはすべて、依存関係がどのように解決され、「時間通り」から「構築中」に解像度を移動するかを効果的に変更します。

サービスはからになる代わりに、の構成でサービスを受けることができます。

namespace Module\Controller; 

class Controller { 
    public function __construct(\Module\Service\Service $service) { 
     $this->service = $service; 
    } 
} 

使用しますが、クラスのメソッドでそれを必要とする$this->service:次の行に沿ってあなたのコードを更新します。

function ($controllers) { 
    $services = $controllers->getServiceLocator(); 
    return new \Module\Controller\Controller($services->get('Module\Service\Service')); 
} 

変更がIssue 5168で議論され、そしてサービスロケータでサービスの注入はアンチパターンである理由this blog postは説明します

は、そのようにように、あなたのコントローラを作成するために、コントローラの工場を使用しています。

+0

異なるアクションが異なるサービスを必要とするコントローラ用のソリューションをお勧めしますか?たとえば、私のindexActionはユーザサービスを必要とし、viewActionはユーザサービスとプロダクトサービスを必要とし、私のaboutUsActionはサービスを全く必要としません。私の指摘は、このようなコントローラの場合、すべてのリクエストに対してコンストラクタ内のすべてのサービスをインスタンス化して渡すのは意味がないということです。 –

+3

@helloworldあなたはそうです。これらのサービスをすべて注入するのは意味をなさないでしょう。私はこれがまさにこの変更のポイントだと思います。開発者にコントローラーに適用されるSingle Responsibility Principleを検討させることです。私にとっては、 "太った"コントローラがあるように思えます。解決策は、これらのアクション用に別々のコントローラを作成することです。特定の例を[codereview SE](codereview.stackexchange.com)に投稿すると、より具体的なフィードバックを得ることができます。 – bishop

+0

フィードバックいただきありがとうございます。コントローラをSRPに準拠させるように作業します。 –

1

あなたはサービス()(しかし、それは悪い習慣だ、FactoryInterfaceを好む)

module.configコントローラプラグインを作成することができます。PHP

'controller_plugins' => [ 
    'factories' => [ 
     'service' => YourNamespace\Mvc\Controller\Plugin\Service\ServiceFactory::class, 
    ], 
], 

YourNamespace \ MVC \コントローラ\プラグイン\サービス\ ServiceFactory.php

<?php 

namespace YourNamespace\Mvc\Controller\Plugin\Service; 

use Interop\Container\ContainerInterface; 
use YourNamespace\Mvc\Controller\Plugin\Service; 
use Zend\ServiceManager\Factory\FactoryInterface; 

class ServiceFactory implements FactoryInterface 
{ 
    /** 
    * @param ContainerInterface $container 
    * @param string $requestedName 
    * @param array $options 
    * @return Service 
    */ 
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 
    { 
     $plugin = new Service(); 
     $plugin->setServiceLocator($container); 
     return $plugin; 
    } 
} 

YourNamespace \ MVC \コントローラ\プラグイン\ Service.php

<?php 

namespace YourNamespace\Mvc\Controller\Plugin; 

use Interop\Container\ContainerInterface; 
use Zend\Mvc\Controller\Plugin\AbstractPlugin; 

/** 
* Plugin: $this->service(); 
*/ 
class Service extends AbstractPlugin 
{ 
    /** 
    * @var ContainerInterface 
    */ 
    protected $serviceLocator; 

    /** 
    * @return ContainerInterface 
    */ 
    public function getServiceLocator() 
    { 
     return $this->serviceLocator; 
    } 

    /** 
    * @param ContainerInterface $serviceLocator 
    * @return Service 
    */ 
    public function setServiceLocator(ContainerInterface $serviceLocator) 
    { 
     $this->serviceLocator = $serviceLocator; 
     return $this; 
    } 

    /** 
    * @param string $name 
    * @return object|bool 
    */ 
    public function __invoke($name = null) 
    { 
     $sl = $this->getServiceLocator(); 
     if (!$name) { 
      return $sl; 
     } 
     if (!$sl->has($name)) { 
      return false; 
     } 
     return $sl->get($name); 
    } 
} 
+0

FactoryInterfaceはどのようになりますか? –

+0

'ServiceFactory'に似ていますが、' $ controller = new YourController();となります。 $ controller-> setService($ container); ' –

関連する問題