为什么我不能在"__construct"中定义对象管理器并在其他方法(操作)之后使用它?ZF2

Sha*_*lav 1 php orm constructor controller zend-framework2

我开始讨论codereview并得到了很好的答案.这个答案就在这里.

所有提示都很好看,现在我想在我的代码中关注它们.

这个答案的作者说,我在所有行动中都得到了对象管理器(某处2次).他建议在init()我的控制器的方法中执行它并将对象管理器分配给$this->objectManager.我试过这个:

在那种情况下,init()zf2 中没有方法,我用了init:

public function __construct() {
    $this->objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
}
Run Code Online (Sandbox Code Playgroud)

关于我正在使用的其他操作:

public function listAction() { 
    $news = $this->objectManager
        ->getRepository('\News\Entity\Item')
        ->findBy(array(), array('created' => 'DESC'));
    // some more code 
}
Run Code Online (Sandbox Code Playgroud)

当我尝试加载页面时,我得到了这个:

Fatal error: Call to a member function get() on a non-object in F:\Server\domains\zf2-skeleton\module\News\src\News\Controller\NewsController.php on line 12
Run Code Online (Sandbox Code Playgroud)

第12行是以下行__construct:

$this->objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
Run Code Online (Sandbox Code Playgroud)

在旧版本我使用类似的:

public function indexAction() {
    $objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
    // how I use $objectManager?
    $news = $objectManager
        ->getRepository('\News\Entity\Item')
        ->findBy($options, array('created'=>'DESC'));
    // some more code
}
Run Code Online (Sandbox Code Playgroud)

为什么接近__construct不起作用?我做错了什么?

github上的文件:

更新

文件MODULE/src/MODULE/Factory/NewsControllerFactory.php内容:

<?

namespace News\Factory;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use News\Controller\NewsController;



class NewsControllerFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        var_dump("bob");
        $objectManager = $serviceLocator->getServiceLocator()->get('Doctrine\ORM\EntityManager');
        return new NewsController($objectManager);
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试var_dump();了那里的东西并意识到,createService在执行期间不会调用该函数.为什么?

小智 5

这是因为尚未设置服务定位器.当您在构造函数中引用它时,$ this-> getServiceLocator()仍然返回null.

如果要设置objectManager以在控制器中使用,我建议使用工厂.它可以更容易地测试您的对象;

class NewsControllerFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $objectManager = $serviceLocator->getServiceLocator()->get('Doctrine\ORM\EntityManager');
        return new NewsController($objectManager);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你的控制器看起来像这样

class NewsController extends AbstractActionController
{
    protected $objectManager;

    public function __construct($objectManager)
    {
        $this->objectManager = $objectManager;
    }
}
Run Code Online (Sandbox Code Playgroud)

以及module.config.php的必要补充

'controllers' => array(
    'factories'     => array(
        'News\Controller\News' => 'News\Factory\NewsControllerFactory',
    )
)
Run Code Online (Sandbox Code Playgroud)