【问题标题】:RenderView in My service我的服务中的渲染视图
【发布时间】:2014-12-13 16:50:25
【问题描述】:

我是 symfony 世界的新手。 我想在我的服务中使用渲染,但是我收到了这个错误

调用未定义的方法renderView

我知道renderView是

的快捷方式
/**
 * Returns a rendered view.
 *
 * @param string $view       The view name
 * @param array  $parameters An array of parameters to pass to the view
 *
 * @return string The rendered view
 */
public function renderView($view, array $parameters = array())
{
    return $this->container->get('templating')->render($view, $parameters);
}

但我不知道我必须在我的服务中注入什么。我什至知道使用php app/console container:debug 命令我可以看到我所有可用的服务,但我不知道如何选择/选择正确的

更新

我尝试添加

arguments: [@mailer,@templating]

但我得到了ServiceCircularReferenceException

更新

我用

更改了我的 service.yml
    arguments: [@service_container]

甚至我的服务

$email = $this->service_container->get('mailer');
$twig = $this->service_container->get('templating');

用于服务邮件(swift)和渲染。

我认为这不是最好的解决方案。我只想注入 mailertemplating

杰森回答后更新 我正在使用 Symfony 2.3

我的服务.yml

services:
    EmailService:
        class: %EmailService.class%
        arguments:  [@mailer,@templating,%EmailService.adminEmail%]

我收到了这个ServiceCircularReferenceException

【问题讨论】:

    标签: php symfony


    【解决方案1】:

    使用构造函数依赖注入(使用 Symfony 3.4 测试):

    class MyService
    {
        private $mailer;
        private $templating;
    
        public function __construct(\Swift_Mailer $mailer, \Twig_Environment $templating)
        {
            $this->mailer     = $mailer;
            $this->templating = $templating;
        }
    
        public function sendEmail()
        {
            $message = $this->templating->render('emails/registration.html.twig');
    
            // ...
        }
    }
    

    无需配置参数。

    【讨论】:

    • 我收到一个错误:Uncaught Exception: Cannot resolve argument $mailer of "App\Controller\EmailController::send()": Cannot autowire service "App\Service\EmailSender": argument "$template" of method "__construct()" has type "Twig_Environment" but this class was not found.
    • Twig_Environment: /** @deprecated since Twig 2.7, use "Twig\Environment" instead */
    【解决方案2】:

    renderView() 是正确的,它只是控制器的快捷方式。使用服务类并注入模板服务时,您只需将函数更改为render()。所以而不是

    return $this->renderView('Hello/index.html.twig', array('name' => $name));
    

    你会使用

    return $this->render('Hello/index.html.twig', array('name' => $name));
    

    Olivia 回复更新:

    如果您遇到循环引用错误,解决它们的唯一方法是注入整个容器。这不是最佳实践,但有时无法避免。当我不得不求助于这个时,我仍然在构造函数中设置我的类变量,这样我就可以像直接注入它们一样行事。所以我会这样做:

    use Symfony\Component\DependencyInjection\ContainerInterface;
    
    class MyClass()
    {
        private $mailer;
        private $templating;
    
        public function __construct(ContainerInterface $container)
        {
            $this->mailer = $container->get('mailer');
            $this->templating = $container->get('templating');
        }
        // rest of class will use these services as if injected directly
    }
    

    旁注,我刚刚在 Symfony 2.5 中测试了我自己的独立服务,并没有通过直接注入邮件程序和模板服务收到循环引用。

    【讨论】:

    • 这很清楚,但是如果我注入 [@mailer,@templating] 我必须注入所有容器。
    • 您正在创建什么类型的服务?它是独立的还是另一个事件的侦听器?除非您正在侦听已经注入这些​​的事件,否则您不应仅使用邮件程序和模板来获得循环引用错误。我猜您正在使用模板来呈现用于您的电子邮件的模板。
    • 这是一个简单的服务,可以创建电子邮件并渲染 emailTemplate
    • 你运行的是什么版本的 Symfony?我知道过去模板环境更频繁地导致循环引用,因为它依赖于许多其他服务,但我已经将邮件程序和模板注入到我的服务中而没有问题。您能否更新您的问题以显示您的服务的完整配置(yml 文件部分)?
    • 假设你有一个应用程序有 10 个服务,它们都注入 Symfony 容器,并将Container 传递给所有这些服务。但是现在你决定扩展 Symfony 容器并制作你自己的具有更多功能的容器。现在你必须回到这 10 个服务并将其更改为你的类。如果您改为使用 ContainerInterface(Symfony 容器和扩展容器都将实现),那么您不必更新任何服务。在此处阅读更多信息(第一个灯泡):symfony.com/doc/current/components/dependency_injection/…
    【解决方案3】:

    这适用于 Symfony +4.2,假设您的应用程序的命名空间是 App 并且您的邮件类服务名为 EmailService。

    在您的服务类上:

    // ...
    
    private $mailer;
    private $templating;
    
    public function __construct( \Swift_Mailer $mailer, \Twig\Environment $templating )
    {
        $this->mailer = $mailer;
        $this->templating = $templating;
    }
    
    public function sendEmailRegistration()
    {
        $message = $this->templating->render('emails/registration.html.twig');
    
        // ...
    }
    
    // ...
    

    在您的 services.yaml 上

    services:
      email_service:
        class: App\Service\EmailService
        arguments: ['@swiftmailer.mailer.default', '@twig']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-12
      • 2011-08-18
      • 1970-01-01
      • 2015-04-16
      • 1970-01-01
      相关资源
      最近更新 更多