获取EntityManager的实体内(Get entityManager inside an En

2019-07-19 05:02发布

我想使用,喜欢的东西:

$em = $this->getEntityManager();

里面一个实体。

我明白我应该做的服务 ,但对于一些测试的目的,我想从一个实体访问。

是否有可能实现这一目标?

我试着:

$em = $this->getEntityManager();
$profile_avatar = $em->getRepository('bundle:Perfils')->findOneByUser($this-getId());

但是,不能正常工作。

致命错误 :调用未定义的方法代理\ webBundleEntityUserProxy :: getEntityManager()在/opt/lampp/htdocs/web/src/Pct/bundle/Entity/User.php上线449

为什么我试图做到这一点这样?

我已经3种用户:Facebook,Twitter和MyOwnWebsite用户。 他们每个人都有型动物头像哪个环节Facebook的个人主页上,Twitter的或其他方式,如果用户myownwebsite,我检索数据库中的一个URL的化身。 现在,我不想创建一个服务,因为我只是试图让它工作,以测试它,而不是创建一个最终部署。 所以这就是为什么我试图从实体调用实体管理器。 我不想,现在,修改配置文件,只要这个实体。

Answer 1:

作为一个评论者指出的(再次),实体内的实体管理器是一个代码味道。 对于OP的具体情况,他希望获得实体管理器,用最少的打扰,简单的setter注入将是最可靠的(与我原来的例如通过构造函数注入)。

对于其他人结束了在这里寻找一个出色的解决方案,以同样的问题,有2种方式来实现这一目标:

  1. 实施ObjectManagerAware接口所建议https://stackoverflow.com/a/24766285/1349295

     use Doctrine\Common\Persistence\ObjectManagerAware; use Doctrine\Common\Persistence\ObjectManager; use Doctrine\Common\Persistence\Mapping\ClassMetadata; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity */ class Entity implements ObjectManagerAware { public function injectObjectManager( ObjectManager $objectManager, ClassMetadata $classMetadata ) { $this->em = $objectManager; } } 
  2. 或者,使用@postLoad / @postPersist生命周期回调并获得使用该实体管理器LifecycleEventArgs参数作为所建议https://stackoverflow.com/a/23793897/1349295

     use Doctrine\Common\Persistence\Event\LifecycleEventArgs; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity * @ORM\HasLifecycleCallbacks() */ class Entity { /** * @ORM\PostLoad * @ORM\PostPersist */ public function fetchEntityManager(LifecycleEventArgs $args) { $this->setEntityManager($args->getEntityManager()); } } 

原来的答案

使用EntityManager从内Entity是非常不好的做法。 这样做违背了脱钩查询的目的,并从实体本身持续操作。

但是,如果你真的,真的,真的需要一个实体管理器中的实体,否则无法做到那么其注入实体。

class Entity
{
    private $em;

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

然后调用为new Entity($em)



Answer 2:

最好的办法是使用生命周期: @ORM\HasLifecycleCallbacks

而当你想要得到的结果,你可以使用相应的事件:

@postLoad
@postPersist
...


Answer 3:

从实体内调用实体管理器是一个不好的做法! 您应该保留实体尽可能简单。

出于什么目的,你需要从实体调用实体管理器?



Answer 4:

我认为你应该做的是,而不是使用实体管理你的实体内,是创造你的实体的自定义存储库。

在你的实体ORM文件,(如果不使用YML或实体类的注解),如下所示添加一个条目:

App\Bundle\Profils: 
# Replace the above as appropiate
    type: entity
    table: (your table)
    ....
    repositoryClass: App\Bundle\CustomRepos\ProfilsRepository
    # Replace the above as appropiate. 
    # I always put my custom repos in a common folder, 
    # such as CustomRepos

现在,创建具有上述命名空间的新的PHP类:

//Your ProfilsRepository.php
<?php
namespace App\Bundle\CustomRepos;

use Doctrine\ORM\EntityRepository;

class ProfilsRepository extends EntityRepository
{
    /**
     * Will return the user url avatar given the user ID
     * @param integer $userID The user id.
       @return string The avatar url
     */
    public function getUserProfile($userId)
    {
       $em = $this->getEntityManager();
       $qb = $em->createQueryBuilder();
       $qb->select... (your logic to retrieve the profil object);

       $query = $qb->getQuery();
       $result = $query->getResult();

       return $result;
    }
}

最后,在你的控制器:

// Your controller
<?php
   namespace <class namespace>;
   ...
   use App\Bundle\CustomRepos\ProfilsRepository;
   use Symfony\Bundle\FrameworkBundle\Controller\Controller;
   ...
   class YourClassNameController extends Controller
   {
      public function yourAction()
      {
         $userId = <get the user ID>;
         // Pass the name of your entity manager to the 
         // getManager function if you have more than one and
         // didn't define any default
         $em = $this->getDoctrine()->getManager();
         $repo = $em->getRepository('Profils');
         $avatar = $repo->getUserProfile($userId);
         ...

      }
   }


Answer 5:

您需要设置services.yml有:

services:
    your_service_name:
        class: AppBundle\Controller\ServiceController
        arguments: [ @doctrine.orm.entity_manager ]

您还需要设置与下面的构造控制器:

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

并使用$this->em在控制器(例如$connection = $this->em->getConnection();



文章来源: Get entityManager inside an Entity