getServiceLocator仅适用于LoginController

时间:2015-10-18 09:02:31

标签: php doctrine-orm zend-framework2 entitymanager

我正在使用ZF2和Doctrine 2 ORM,使用以下内容:

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

似乎在LoginController中工作,但似乎在任何其他控制器中都不起作用,可能是什么原因? (所有控制器都在同一个应用程序下)

<?php

namespace OEC;

use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\Mvc\MvcEvent;
use Zend\ServiceManager\ServiceManager;

class Module implements AutoloaderProviderInterface
{


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

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

    public function onBootstrap(MvcEvent $e){

            $e->getApplication()->getEventManager()->getSharedManager()->attach('Zend\Mvc\Controller\AbstractController', 'dispatch', function($e) {
            $controller      = $e->getTarget();


                if ($controller instanceof Controller\LoginController) {
                    $controller->layout('login/login.phtml');
                } else {
                    $controller->layout('layout/layout.phtml');
                }
        }, 100);
    }

    public function getServiceConfig(){
        return array(
            'factories' => array(
                'Zend\Authentication\AuthenticationService' => function($serviceManager) {
                    return $serviceManager->get('doctrine.entitymanager.orm_default');
                }
            )
        );
    }


}

?>

不断获取此错误在null

上调用成员函数get()

我的工作负责人

<?php

namespace OEC\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Session\Container;
use OEC\Controller\CommonController;

class LoginController extends AbstractActionController{

    public function indexAction(){

        $session = self::checkUserLoginAction();

        if( $session ){
            return $this->redirect()->toUrl( MAIN_URL . 'oec/view/dashboard');
        }

        return new ViewModel();
    }

    public function loginAction(){


        $username = $this->getRequest()->getPost('username');
        $password = $this->getRequest()->getPost('password');

        try{
            $objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');

            $user = $objectManager->getRepository('OEC\Entity\User')->findOneBy(array('username' => $username, 'password' => md5($password)  ));

            if( !$user ){
                print_r("not found");exit;
            }

            if( $user && $user->getId() != 0 ){

                $session = new Container('user');
                $session->userId = $user->getId();
                $session->username = $user->getUsername();
                $session->userType = $user->getUserTypeId();

                CommonController::json(true, "successfully logged in", NULL, "view/dashboard");exit;

            }

        }catch(\Doctrine\ORM\NoResultException $e) {
            print_r("error");exit;
        }

    }


    public static function checkUserLoginAction(){

        $session = new Container('user');

        if( $session->offsetExists('username') && $session->offsetExists('userId') && $session->offsetExists('userType') ){

            return array(
              "username" => $session->offsetGet('username'),
              "name" => $session->offsetGet('name'),
              "userType" => $session->offsetGet('userType')
            );

        }else{
            return false;
        }

    }

    public function logoutAction(){

        $session = new Container('user');
        $session->getManager()->destroy();

        return $this->redirect()->toUrl( MAIN_URL . 'oec/view/login');

    }

}

我没有工作的控制器

<?php
namespace OEC\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

class BloodTypeController extends AbstractActionController
{

    public function indexAction()
    {
        return new ViewModel();
    }

    public function listAll(){

        $objectManager = $this->getServiceLocator()->get('doctrine');

        $bloodRep = $objectManager->getRepository('OEC\Entity\Blood');
        $bloods = $bloodRep->findAll();

        $bloodsArr = array();

        foreach( $bloods as $blood ){

            array_push($bloodsArr , $blood->toArray() );
        }

        $objectManager->close();

        return $bloods;
    }
}

2 个答案:

答案 0 :(得分:1)

您可以使用3种不同的方式来获取服务($serviceManager->get('doctrine.entitymanager.orm_default'); $objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager'); $objectManager = $this->getServiceLocator()->get('doctrine'); 实例):

Doctrine

这第三个是错的。您正在获取EntityManager服务,以获取您需要拨打->getEntityManager();的{​​{1}}个实例

$objectManager = $this->getServiceLocator()->get('doctrine')->getEntityManager();

'doctrine'服务通常在 Symfony框架中提供,并且在Zend Framework 2中不起作用

如果建议始终使用一个服务名称:

$objectManager = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');

这应该有用。

另一种解决方案

另一个更好的解决方案是使控制器依赖于ObjectManager,在Controller类中使用the doctrine ObjectManagerAwareInterface并在工厂中注入服务。

要执行此操作,您需要在module.config.php controllers下的factories注册您的控制器,如下所示:

'controllers' => array(
    'factories' => array(
        'OEC\Controller\BloodTypeController' => 'OEC\Controller\Factory\BloodTypeControllerFactory'
    )
)

然后像这样创建一个BloodTypeControllerFactory工厂类:

<?php
namespace OEC\Controller\Factory;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use OEC\Controller\BloodTypeController;

class BloodTypeControllerFactory implements FactoryInterface
{
    /**
     * @param  ServiceLocatorInterface $serviceLocator
     * @return BloodTypeController
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $controllerPluginManager = $serviceLocator;
        $serviceManager = $controllerPluginManager->get('ServiceManager');
        $objectManager = $serviceManager->get('doctrine.entitymanager.orm_default');
        return new BloodTypeController($objectManager);
    }
}

然后将以下内容添加到您的OEC\Controller\BloodTypeController

<?php
namespace OEC\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Doctrine\Common\Persistence\ObjectManager;

class BloodTypeController extends AbstractActionController implements ObjectManagerAwareInterface
{
    /**
     * @var ObjectManager
     */
    protected $objectManager;

    /**
     * @param ObjectManager $objectManager
     */
    public function __construct(ObjectManager $objectManager){
        $this->objectManager = $objectManager
    }

    /**
     * Set the object manager
     *
     * @param ObjectManager $objectManager
     */
    public function setObjectManager(ObjectManager $objectManager)
    {
        $this->objectManager = $objectManager;
    }

    /**
     * Get the object manager
     *
     * @return ObjectManager
     */
    public function getObjectManager()
    {
        return $this->objectManager();
    }

    public function indexAction()
    {
        return new ViewModel();
    }

    public function listAll()
    {
        $objectManager = $this->getObjectManager();

        //etc
    }
}

答案 1 :(得分:0)

doctrine不是获取实体经理的有效名称,有两种方法直接通过服务管理器获取它:

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

您在LoginController中的操作会触发标准工厂并始终返回实体经理orm_default

$this->getServiceLocator()->get("doctrine.entitymanager.orm_default");
如果在最后一个点之后替换orm_default

将触发抽象工厂并返回实体管理器orm_default或其他实体管理器。这是获取实体经理的最常用方式。