【问题标题】:How can I use doctrine method inside my service (Symfony 4)?如何在我的服务中使用学说方法(Symfony 4)?
【发布时间】:2019-03-05 09:45:32
【问题描述】:

我在 Symfony 中创建了我自己的第一个服务:

// src/Service/PagesGenerator.php 

namespace App\Service;

class PagesGenerator
{
    public function getPages()
    {

      $page = $this->getDoctrine()->getRepository(Pages::class)->findOneBy(['slug'=>$slug]);

        $messages = [
            'You did it! You updated the system! Amazing!',
            'That was one of the coolest updates I\'ve seen all day!',
            'Great work! Keep going!',
        ];

        $index = array_rand($messages);

        return $messages[$index];
    }
}

但我收到错误消息:

试图调用类的名为“getDoctrine”的未定义方法 “应用\服务\页面生成器”。

然后我尝试在我的 services.yaml 中添加:

PagesGenerator:
    class: %PagesGenerator.class%
    arguments:
      - "@doctrine.orm.entity_manager"

然后我收到错误消息:

文件“/Users/work/project/config/services.yaml”不包含 /Users/work/project/config/services.yaml 中的有效 YAML(即 加载到资源“/Users/work/project/config/services.yaml”中)。

【问题讨论】:

  • Symfony 正在使用称为依赖注入的神奇模式。不要在services.yaml 中为您的服务提供任何参数,而是在您的服务中调用__construct(EntityManagerInterface $em) 并让Symfony 注入您的实体管理器。在我看来,这要清楚得多。
  • @GasKa 非常感谢。这听起来真的很好。能给我举个例子吗。我试图将此行放入我的服务中,但我收到错误 syntax error, unexpected '$em'
  • 我认为您使用了$em 而不是$this->em。此外,您必须在__construct() 之前为您的服务声明此属性。
  • 正如我在上一个问题中所说的那样:阅读文档。使用自动装配是 Symfony 最佳实践的一部分。
  • 但不阅读文档?再次:使用自动装配。

标签: php symfony doctrine-orm


【解决方案1】:

所以,在 cmets 中,我说让 Symfony 完成他的工作并自动装配 EntityManager 会更好。这是你应该做的。另外,您能否告诉我们您使用的是什么 Symfony 版本以及是否启用了自动装配(检查 services.yaml 是否有此功能)?

<?php

namespace App\Service;

use Doctrine\ORM\EntityManagerInterface;

class PagesGenerator
{
    public function __construct(EntityManagerInterface $em) {
        $this->em = $em;
    }

    public function getPages()
    {

      $page = $this->em->getRepository(Pages::class)->findOneBy(['slug'=>$slug]);

        $messages = [
            'You did it! You updated the system! Amazing!',
            'That was one of the coolest updates I\'ve seen all day!',
            'Great work! Keep going!',
        ];

        $index = array_rand($messages);

        return $messages[$index];
    }
}

【讨论】:

  • 这听起来很对,但是如果我需要调用另一个经理来获取我的存储库会发生什么?由于 EntityManagerInterface 没有 getManager() 属性,我只能从“默认”调用存储库。如果我尝试从服务中执行 $this->getDoctrine() 我会收到错误 :: Call to a member function has() on null
【解决方案2】:

确保使用 YAML 的“空格”使用正确的缩进。

一个 YAML 文件使用空格作为缩进,你可以使用 2 或 4 个空格 缩进,但没有制表符 read more about this

symfony 3.3 之前

例如,我们在AppBundle/FrontEndBundle/Services 中有服务sms_manager

services:
    AppBundle.sms_manager:
        class: AppBundle\FrontEndBundle\Services\SmsManager
        arguments: [ '@service_container' ,'@doctrine.orm.entity_manager' ]

那么您的服务可以在构造函数中接收您的参数

<?php

namespace AppBundle\FrontEndBundle\Services;

use Symfony\Component\DependencyInjection\ContainerInterface as Container;

class SmsManager {
    private $container;
    private $DM;

    public function __construct( Container $container, \Doctrine\ORM\EntityManager $DM ) 
    {
        $this->container = $container;
        $this->DM        = $DM;
    }

    /**
    * @return \Doctrine\ORM\EntityManager
    */

    public function getDoctrine() {
      return $this->DM;
    }

}

使用 Symfony 3.3 或更高版本,

Is there a way to inject EntityManager into a service

use Doctrine\ORM\EntityManagerInterface

class PagesGenerator
{
    private $em;

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

    // ...
}

【讨论】:

  • 我知道不建议再注入您的容器。但建议从 Symfony 4.x 开始。无论如何,避免这种情况
  • @GasKa 他没有提到版本。
  • 正确,我认为他有 Symfony 3.x 或 Symfony 4.x,一切都如我所说。我看到你编辑了你的帖子。好的!先看看他的回复
  • 我正在使用 Symfony 4
【解决方案3】:

使用 Symfony 4 和新的自动装配,您可以轻松地注入一定数量的类

要找出可用于自动装配的类/接口,请使用以下命令:

bin/console   debug:autowiring 

我们将使用这个:

Doctrine\ORM\EntityManagerInterface (doctrine.orm.default_entity_manager)

让我们来吧,在 getPages 函数之前添加它

/**
 * @var EntityManagerInterface
 */
private $em;

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

那么你可以这样使用它:

  $page = $this->em->getRepository(Pages::class)->findOneBy(['slug'=>$slug]);

希望对你有帮助!

【讨论】:

  • 谢谢!运行良好
猜你喜欢
  • 1970-01-01
  • 2018-06-22
  • 2018-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多