简体   繁体   English

如何让Doctrine在Symfony2上的辅助函数中工作

[英]How to get Doctrine to work inside a helper function on Symfony2

I need to get doctrine working inside my helper, im trying to use like i normaly do in a controller: 我需要在我的帮助器中使用doctrine,我试着在控制器中像我一样正常使用:

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

But this gave me: 但这给了我:

FATAL ERROR: CALL TO UNDEFINED METHOD DONE\\PUNCTISBUNDLE\\HELPER\\UTILITYHELPER::GETDOCTRINE() IN /VAR/WWW/VHOSTS/PUNCTIS.COM/HTTPDOCS/SRC/DONE/PUNCTISBUNDLE/HELPER/UTILITYHELPER.PH 致命错误:调用未完成的方法DONE \\ PUNCTISBUNDLE \\ HELPER \\ UTILITYHELPER :: GETDOCTRINE()/VAR/WWW/VHOSTS/PUNCTIS.COM/HTTPDOCS/SRC/DONE/PUNCTISBUNDLE/HELPER/UTILITYHELPER.PH

What Im missing here? 我在这里失踪了什么?

EDIT: 编辑:

services file 服务文件

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

Firts lines of helper file 第一行辅助文件

<?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;
    }

The problem here is that your Helper class is not container-aware; 这里的问题是你的Helper类不是容器感知的; that is, it has no idea about all the services Symfony has loaded (monolog, twig, ...and doctrine). 也就是说,它不知道Symfony已经加载的所有服务(monolog,twig,...和doctrine)。

You fix this by passing "doctrine" to it. 你通过将“教义”传递给它来解决这个问题。 This is called Dependency Injection, and is one of the core things that makes Symfony awesome. 这称为依赖注入,是Symfony令人敬畏的核心内容之一。 Here's how it works: 以下是它的工作原理:

First, give your Helper class a place for the Doctrine service to live, and require it in the Helper's constructor: 首先,让你的Helper类为Doctrine服务提供一个生存的地方,并在Helper的构造函数中要求它:

class UtilityHelper
{
    private $doctrine;

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

    public function doSomething()
    {
        // Do something here
    }
}

Then, you use services.yml to define how Symfony should construct that instance of Helper: 然后,使用services.yml来定义Symfony应该如何构造Helper实例:

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

In this case, @doctrine is a placeholder that means "insert the Doctrine service here". 在这种情况下, @doctrine是占位符,表示“在此处插入Doctrine服务”。

So now, in your Controller, or in anything else that is container-aware, you can get access to Doctrine through the Helper class like this: 现在,在您的Controller中,或者在容器感知的任何其他内容中,您可以通过Helper类访问Doctrine,如下所示:

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

EDIT 编辑

After looking at your edit, it appears that you're injecting the entire service container into the Helper class. 查看编辑后,您似乎将整个服务容器注入Helper类。 That's not a best practice -- you should only inject what you need. 这不是最好的做法 - 你应该只注射你需要的东西。 However, you can still do it: 但是,你仍然可以这样做:

services.yml services.yml

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

UtilityHelper.php 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(...)  
    }
}

I've included a few comments there that highlight some common pitfalls. 我在那里添加了一些评论,突出了一些常见的陷阱。 Hope this helps. 希望这可以帮助。

Why don't you create the method in the repository and then call the method from within your helper? 为什么不在存储库中创建方法,然后从帮助程序中调用方法? Like in this link: 喜欢这个链接:

https://gist.github.com/peterjmit/1986048 https://gist.github.com/peterjmit/1986048

In Helper, Services etc you cannot use it like in actions. 在帮助程序,服务等中,您无法像在操作中那样使用它。 You need to pass it like argument to youre Helper via service description in conf file(services.yml or *.xml). 您需要通过conf文件(services.yml或* .xml)中的服务描述将参数传递给您的Helper。

Example: 例:

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

And dont forget catch it in __construct of youre Helper. 不要忘记在你帮助的__construct中抓住它。

Example: 例:

use Doctrine\ORM\EntityManager;
....    

private $em;
public function __construct(EntityManager $em)
{
  $this->em = $em;
}

You can use it like: 您可以像以下一样使用它:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM