我想使用,喜欢的东西:
$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的化身。 现在,我不想创建一个服务,因为我只是试图让它工作,以测试它,而不是创建一个最终部署。 所以这就是为什么我试图从实体调用实体管理器。 我不想,现在,修改配置文件,只要这个实体。
作为一个评论者指出的(再次),实体内的实体管理器是一个代码味道。 对于OP的具体情况,他希望获得实体管理器,用最少的打扰,简单的setter注入将是最可靠的(与我原来的例如通过构造函数注入)。
对于其他人结束了在这里寻找一个出色的解决方案,以同样的问题,有2种方式来实现这一目标:
实施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; } }
或者,使用@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)
最好的办法是使用生命周期: @ORM\HasLifecycleCallbacks
而当你想要得到的结果,你可以使用相应的事件:
@postLoad
@postPersist
...
从实体内调用实体管理器是一个不好的做法! 您应该保留实体尽可能简单。
出于什么目的,你需要从实体调用实体管理器?
我认为你应该做的是,而不是使用实体管理你的实体内,是创造你的实体的自定义存储库。
在你的实体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);
...
}
}
您需要设置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();
)