【问题标题】:How to get Doctrine to work inside a helper function on Symfony2如何让 Doctrine 在 Symfony2 的辅助函数中工作
【发布时间】:2013-03-11 05:25:21
【问题描述】:

我需要让教义在我的助手中工作,我试图像我通常在控制器中那样使用:

$giftRepository = $this->getDoctrine( )->getRepository( 'DonePunctisBundle:Gift' );

但这给了我:

致命错误:调用未定义的方法 完成\PUNCTISBUNDLE\HELPER\UTILITYHELPER::GETDOCTRIN() IN /VAR/WWW/VHOSTS/PUNCTIS.COM/HTTPDOCS/SRC/DONE/PUNCTISBUNDLE/HELPER/UTILITYHELPER.PH

我在这里缺少什么?

编辑:

服务文件

services:
    templating.helper.utility:
        class: Done\PunctisBundle\Helper\UtilityHelper
        arguments: [@service_container]
        tags:
            - { name: templating.helper, alias: utility }

帮助文件的前几行

<?php
namespace Done\PunctisBundle\Helper;

use Symfony\Component\Templating\Helper\Helper;
use Symfony\Component\Templating\EngineInterface;



class UtilityHelper extends Helper {

    /*
     * Dependency injection
     */

    private $container;

    public function __construct( $container )
    {
        $this->container = $container;
    }

【问题讨论】:

    标签: php symfony dependency-injection doctrine


    【解决方案1】:

    这里的问题是您的 Helper 类不是容器感知的;也就是说,它不知道 Symfony 加载的所有服务(独白、树枝……和教义)。

    您可以通过将“教义”传递给它来解决此问题。这被称为依赖注入,它是使 Symfony 很棒的核心内容之一。以下是它的工作原理:

    首先,为您的 Helper 类提供一个存放 Doctrine 服务的位置,并在 Helper 的构造函数中要求它:

    class UtilityHelper
    {
        private $doctrine;
    
        public function __construct($doctrine)
        {
            $this->doctrine = $doctrine;
        }
    
        public function doSomething()
        {
            // Do something here
        }
    }
    

    然后,您使用 services.yml 来定义 Symfony 应该如何构造该 Helper 实例:

    services:
        helper:
            class: Done\PunctisBundle\Helper\UtilityHelper
            arguments: [@doctrine]
    

    在这种情况下,@doctrine 是一个占位符,意思是“在此处插入 Doctrine 服务”。

    所以现在,在您的 Controller 或其他任何可感知容器的东西中,您可以通过 Helper 类访问 Doctrine,如下所示:

    class SomeController()
    {
        public function someAction()
        {
            $this->get("helper")->doctrine->getRepository(...);
        }
    }
    

    编辑

    查看您的编辑后,您似乎将整个服务容器注入到 Helper 类中。这不是最佳实践——你应该只注入你需要的东西。但是,您仍然可以这样做:

    services.yml

    services:
        helper:
            class: Done\PunctisBundle\Helper\UtilityHelper
            arguments: [@service_container]
    

    UtilityHelper.php

    class UtilityHelper
    {
        private $container;
    
        public function __construct($container)
        {
            $this->container = $container;
        }
    
        public function doSomething()
        {
            // This won't work, because UtilityHelper doesn't have a getDoctrine() method:
            // $this->getDoctrine()->getRepository(...)
    
            // Instead, think about what you have access to...
            $container = $this->container;
    
            // Now, you need to get Doctrine
    
            // This won't work... getDoctrine() is a shortcut method, available only in a Controller
            // $container->getDoctrine()->getRepository(...)
    
            $container->get("doctrine")->getRepository(...)  
        }
    }
    

    我在其中包含了一些突出一些常见缺陷的 cmets。希望这会有所帮助。

    【讨论】:

    • 我对如何在现有文件中插入这些新数据有点困惑,请查看我对问题所做的编辑,以便您可以帮助我更好地修改它们跨度>
    • 根据您的更新编辑了我的答案。如果这不起作用,请告诉我。
    【解决方案2】:

    在 Helper、Services 等中,您不能像在操作中那样使用它。 您需要通过 conf 文件(services.yml 或 *.xml)中的服务描述将它作为参数传递给您的 Helper。

    例子:

      services:
       %service_name%:
        class: %path_to_youre_helper_class%
        arguments: [@doctrine.orm.entity_manager]
        tags:
            - { name: %name% }
    

    别忘了在你的 Helper 的 __construct 中捕获它。

    例子:

    use Doctrine\ORM\EntityManager;
    ....    
    
    private $em;
    public function __construct(EntityManager $em)
    {
      $this->em = $em;
    }
    

    你可以像这样使用它:

    public function myMethod()
    {
      $repo = $this->em->getRepository('DonePunctisBundle:Gift');
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-10
      • 1970-01-01
      • 1970-01-01
      • 2019-07-20
      • 1970-01-01
      • 2015-06-10
      • 2015-10-17
      • 1970-01-01
      • 2016-03-27
      相关资源
      最近更新 更多