0

編集 1: 自分自身をうまく説明できなかったようです。クラス Foo はエンティティではありません。エンティティマネージャーにアクセスしたい汎用モデルです。

編集 2: 私の質問に対する答えはないと思います。基本的に、このクラスがサービス マネージャーによって呼び出されなくても EntityManager にアクセスできるクラスが必要でした。これは、サービス マネージャーによっても呼び出されないクラスによって呼び出される可能性があるためです。言い換えれば、私は ZF1 で Zend_Registry が達成していたことを達成しようとしていました。私がやろうとしていることを行う別の方法を見つけなければなりません。

コントローラーで行ったのと同様の方法で、モデルでDoctrineのエンティティマネージャーにアクセスしようとしています:

$this->getServiceLocator()->get('Doctrine\ORM\EntityManager');

ZF2 マニュアル (http://framework.zend.com/manual/2.0/en/modules/zend.service-manager.quick-start.html) には次のように書かれています。

デフォルトでは、Zend Framework MVC は、Zend\ServiceManager\ServiceLocatorAwareInterface を実装する任意のクラスに、Zend\ServiceManager\ServiceLocatorInterface の実装である ServiceManager インスタンスを挿入するイニシャライザを登録します。

そこで、次のクラスを作成しました。

<?php
namespace MyModule\Model;

use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class Foo implements ServiceLocatorAwareInterface
{
    protected $services;

    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
    {
         $this->services = $serviceLocator;
    }

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

    public function test()
    {
        $em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
    }
}   

次に、別のクラスから、このクラスを次のように呼び出します。

$foo = new \MyModule\Model\Foo();
$foo->test()

次のエラーがスローされます。

PHP 致命的なエラー: 非オブジェクトでのメンバー関数 get() の呼び出し

だから、私はどこかで何かが欠けていると思いますが、何ですか?どこ?どのように?おそらく、エンティティマネージャーに簡単にアクセスできますか?

ありがとう!

4

2 に答える 2

1

あなたが見逃している唯一のことは、モデルクラスを呼び出し可能なリストに追加し、サービスマネージャーを介して取得することだと思います。

したがって、基本的にこれをmodule.conf.phpに追加します。

return array(
    'service_manager' => array(
        'invokables' => array(
            'MyModule\Model\Foo' => 'MyModule\Model\Foo',
        ),
    ),
);

モデル オブジェクトを次のようにインスタンス化します (コントローラーの場合)。

$foo = $this->getServiceLocator()->get('MyModule\Model\Foo');
$foo->test();
于 2013-02-19T09:06:58.400 に答える
1

あなたの質問から、主に 2 つの誤解があることがわかります。1 つは設計戦略 (モデルに EntityManager を挿入する) に関するもので、もう 1 つはサービス マネージャー (ServiceLocatorAwareInterface) との連携方法に関するものです。私の答えでは、2番目に焦点を当てようとします。

イニシャライザは、サービス マネージャからアクセスされる各インスタンスに対して呼び出される php クロージャであり、このインスタンスが返されます。

Initializer の例を次に示します。

// Line 146 - 150 of Zend\Mvc\Service\ServiceManagerConfig class + comments

$serviceManager->addInitializer(function ($instance) use ($serviceManager) {
        if ($instance instanceof ServiceManagerAwareInterface) {
            $instance->setServiceManager($serviceManager);
        }
    });

Service Manager が ServiceManagerAwareInterface インターフェイスを実装するインスタンス/オブジェクトを返すように要求されるたびに、Service Manager インスタンスをセットアップ/挿入します。

ちなみに、前のコードでは、setServiceManagerメソッドを定義していないため、インターフェイスを正しく実装することを省略しました。ただし、これはあなただけの問題ではありません。まず、サービス マネージャーがモデルに自分自身を注入する場合、たとえばクラスに複雑な依存関係がある場合は、ファクトリを介してモデル インスタンスを呼び出す/構築する必要があります (このプロセス中にイニシャライザーが呼び出されます)。

[編集]

例:

あなたの MyModule で

namespace MyModule;
use Zend\ModuleManager\Feature\ServiceProviderInterface;
use MyModule\Model\Foo;

class Module implements ServiceProviderInterface{

//Previous code

public function getServiceConfig()
{
    return array(
        'instances' => array(
            'myModelClass'        => new Foo(),
            ),
       );

}

ここで、Foo インスタンスが必要な場合は、Service Manager を呼び出す必要があります。

$serviceManager->get('myModelClass');

メソッドの定義を忘れないでくださいsetServiceManager。そうしないと、ServiceManagerAwareInterface を正しく実装できません!

于 2013-01-23T10:14:09.540 に答える