zf2:如何在Model中获取Service Locator

时间:2013-07-03 08:26:30

标签: zend-framework2

我尝试了其他帖子和示例中的一些想法,但我仍然没有解决方案。 我无法在我的模型中收到servicelocator。

我的Module.php在函数getServiceConfig()中包含以下工厂:

'Backend\Model\Beuser' => function($sm){
                     $serviceLocator = $sm->getServiceLocator();
                     return new \Backend\Model\Beuser($serviceLocator); 
               },

我的模型Beuser.php看起来像:

namespace Backend\Model;

use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;


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

class Beuser implements ServiceLocatorAwareInterface
{

    public $idx_be_user;
    public $be_user_email;
    public $be_user_password;
    public $be_user_firstname;
    public $be_user_lastname;
    public $be_user_phone;
    public $be_user_photo;
    public $be_user_shorttext;

     protected $inputFilter;    

     protected $serviceLocator;

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

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

    public function exchangeArray($data)
    {

        $this->idx_be_user          = (!empty($data['idx_be_user'])) ? $data['idx_be_user'] : null;
        $this->be_user_email        = (!empty($data['be_user_email'])) ? $data['be_user_email'] : null;
        $this->be_user_password  = (!empty($data['be_user_password'])) ? $data['be_user_password'] : null;
        $this->be_user_firstname = (!empty($data['be_user_firstname'])) ? $data['be_user_firstname'] : null;
        $this->be_user_lastname  = (!empty($data['be_user_lastname'])) ? $data['be_user_lastname'] : null;
        $this->be_user_phone        = (!empty($data['be_user_phone'])) ? $data['be_user_phone'] : null;
        $this->be_user_photo        = (!empty($data['be_user_photo'])) ? $data['be_user_photo'] : null;
        $this->be_user_shorttext = (!empty($data['be_user_shorttext'])) ? $data['be_user_shorttext'] : null;

    }

     public function getArrayCopy()
    {
        return get_object_vars($this);
    }

     public function setInputFilter(InputFilterInterface $inputFilter)
    {
        throw new \Exception("Not used");
    }

    public function getInputFilter()
    {

         var_dump($this->getServiceLocator());
         die();
        if (!$this->inputFilter) {
            $inputFilter = new InputFilter();
            $factory     = new InputFactory();

            $inputFilter->add($factory->createInput(array(
                'name'     => 'idx_be_user',
                'required' => true,
                'filters'  => array(
                    array('name' => 'Int'),
                ),
            )));

            $inputFilter->add($factory->createInput(array(
                'name'     => 'be_user_email',
                'required' => true,
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name'    => 'StringLength',
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 1,
                            'max'      => 100,
                        ),
                    ),
                         /*
                          array(
                              'name'    => 'Db\NoRecordExists',
                              'options' => array(
                                    'table'     => 'users',
                                        'field'     => 'email',
                            //      'adapter'   => $this->getServiceLocator()->get('dbAdapter'),
                              ),
                         ), 
                          */

                ),
            )));

            $inputFilter->add($factory->createInput(array(
                'name'     => 'be_user_password',
                'required' => true,
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name'    => 'StringLength',
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 6,
                            'max'      => 100,
                        ),
                    ),  
                ),
            )));

            $inputFilter->add($factory->createInput(array(
                'name'     => 'be_user_firstname',
                'required' => true,
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name'    => 'StringLength',
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 1,
                            'max'      => 100,
                        ),
                    ),
                ),
            )));

            $inputFilter->add($factory->createInput(array(
                'name'     => 'be_user_lastname',
                'required' => true,
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name'    => 'StringLength',
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 1,
                            'max'      => 100,
                        ),
                    ),
                ),
            )));

            $inputFilter->add($factory->createInput(array(
                'name'     => 'be_user_phone',
                'required' => true,
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name'    => 'StringLength',
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 1,
                            'max'      => 100,
                        ),
                    ),
                ),
            )));


                $inputFilter->add(
                $factory->createInput(array(
                    'name'     => 'be_user_photo',
                    'required' => false,
                ))
            );


            $inputFilter->add($factory->createInput(array(
                'name'     => 'be_user_shorttext',
                'required' => false,
                'filters'  => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name'    => 'StringLength',
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 5,
                            'max'      => 255,
                        ),
                    ),
                ),
            )));

            $this->inputFilter = $inputFilter;
        }

        return $this->inputFilter;
    }

}

但是  var_dump($this->getServiceLocator()); 返回NULL。这就是为什么要调用$this->getServiceLocator()->get('something')的原因 创造一个  PHP Fatal error: Call to a member function get()[...]

你能帮我找到问题吗?

PS:我也尝试过以下工厂:

 'Backend\Model\Beuser' => function($sm){
        $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
        $beuser = new \Backend\Model\Beuser();
        $beuser->setDbAdapter($dbAdapter);
        return $beuser;
    },

my module.php:

namespace Backend;

use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\Authentication\Storage;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Authentication\AuthenticationService;
use Zend\Authentication\Adapter\DbTable as AuthAdapter;
use Zend\Authentication\Result as Result;
use Zend\Session\Container; // We need this when using sessions

//Be User
use Backend\Model\Beuser;
use Backend\Model\BeuserTable;


class Module implements AutoloaderProviderInterface
{

    public function getAutoloaderConfig()
    {
         return array(
             'Zend\Loader\ClassMapAutoloader' => array(
                __DIR__ . '/autoload_classmap.php'
             ),
             'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
             ),
         );
     }

    public function getConfig()
    {
    return include __DIR__ . '/config/module.config.php';
    }

    public function getServiceConfig()
   {
        return array(

               //factories
            'factories'=>array(

                    //Storage
                   'BackendStorage' => function($sm){
                        return new BackendStorage('backend'); 
                    },                   
                    //DB Adapter
                    'dbAdapter' => function($sm) {          
                         $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');                       
                         return $dbAdapter;                      
               },                             
                    //nur DB
                    'db'  => function($sm) {
                        $dba= $sm->get('dbAdapter');
                        $db = new db\Db($dba);
                        return $db;
                    },                   
                    //mache Auth Info verfuegbar                            
                    'AuthService' => function($sm) {    
                        //$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');                                             
                        $dbTableAuthAdapter  = new AuthAdapter($sm->get('dbAdapter'),'tbl_be_user','be_user_email','be_user_password', 'MD5(?)');               
                        //$authService = new AuthenticationService();               
                        $authService = new AuthenticationService(new Storage\Session('Auth_Backend'));
                        $authService->setAdapter($dbTableAuthAdapter);
                        return $authService;                    

                    },  
                    //Navigation
                    'NavigationFactory' => 'Backend\Service\NavigationFactory', 

                    // Backend User       
                    'Backend\Model\BeuserTable' =>  function($sm) {
                    $tableGateway = $sm->get('BeuserTableGateway');
                    $table = new BeuserTable($tableGateway);
                    return $table;
                },                              
               'BeuserTableGateway' => function ($sm) {
                    $dbAdapter = $sm->get('dbAdapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Beuser());
                    return new TableGateway('tbl_be_user', $dbAdapter, null, $resultSetPrototype);
                },  

                    'Backend\Model\Beuser' => function($sm){
                        $model = new \Backend\Model\Beuser(); 
                        $model->setServiceLocator($sm);

                        return $model;
                    },

            ),



        );                

    }

     public function getViewHelperConfig()
    {
        return array(
            'invokables' => array(
                'PageTitle' => 'Backend\ViewHelper\PageTitle',  
            ),
            'factories' => array(
                 //hasIdentity true or false
                 'AuthStatusFactory' => function ($serviceManager) {
                      // Get the service locator 
                $serviceLocator = $serviceManager->getServiceLocator();
                // pass it to your helper 
                return new \Backend\ViewHelper\AuthStatusFactory($serviceLocator);
             },
                 'BeUserName' => function ($serviceManager) {
                      // Get the service locator 
                $serviceLocator = $serviceManager->getServiceLocator();
                // pass it to your helper 
                return new \Backend\ViewHelper\BeUserName($serviceLocator);
            },
            ) 
        );
    }


}

2 个答案:

答案 0 :(得分:7)

您通过一个不存在的构造函数传递它...只需使用setter。 Service Manager实现了ServiceLocatorInterface,只需将其传递给您的模型。

更改您的服务配置:

'Backend\Model\Beuser' => function($sm){
    $model = new \Backend\Model\Beuser(); 
    $model->setServiceLocator($sm);

    return $model;
},

Controller中的访问示例:

public function testAction()
{
    // The service manager will then inject itself into your model
    // when it is instantiated.
    $myModel = $this->getServiceLocator()->get('Backend\Model\Beuser');

    // now you have the Service Locator injecte4d into your model ..
    //var_dump($myModel->getServiceLocator());
}

您还需要确保使用服务定位器来获取您需要创建的任何模型实例,否则不会注入任何内容:

'BeuserTableGateway' => function ($sm) {
     $dbAdapter = $sm->get('dbAdapter');
     $resultSetPrototype = new ResultSet();
     // Beuser will not have the service locator injected below..
     // and will return null if the object wasn't created via the service manager.
     //$resultSetPrototype->setArrayObjectPrototype(clone $sm->get('Backend\Model\Beuser'));
     $resultSetPrototype->setArrayObjectPrototype(new Beuser());

     return new TableGateway('tbl_be_user', $dbAdapter, null, $resultSetPrototype);
 }, 

答案 1 :(得分:0)

谢谢安德鲁 - 你的答案向我展示了正确的方式:-) 我解决了我的问题。 我忘了通过ServiceLocator在控制器中获取Album模型。

控制器:

public function addAction(){
    [...]
    //Adapter an Beuser Model uebergeben 
    $beuser->setDbAdapter($this->getServiceLocator()->get('dbAdapter'));
    [...]
 }

 public function editAction(){
    [...]
    //Adapter an Beuser Model uebergeben 
    $beuser->setDbAdapter($this->getServiceLocator()->get('dbAdapter'));
    [...]
 }

模特:

private $adapter;   

public function setDbAdapter($dbAdapter) {
    $this->adapter = $dbAdapter;
}

public function getDbAdapter() {
    return $this->adapter;       
}

现在我可以用这种方式在模型中调用适配器

$this->getDbAdapter();