一个Doctrine实体可以自己阅读吗?

时间:2015-11-19 00:03:59

标签: php doctrine-orm doctrine datamapper single-responsibility-principle

只是好奇..我有一些像这样的代码:

//$em is EntityManager of Doctrine
//$className is a type that uses polymorphism (subtype of a parent type)
$pricing = $em->getRepository($className)->findOneBy(array(
    'active' => true,
    'product_id' => (int) $this->id
));

//gets serialization of certain variables of $className
return $pricing->getSerialization();

但是......我可以在实体($ className)中移动findOneBy方法,而不是在$className之外调用getSerialization() ,而不是从那里返回类参数?

我想这是不可能的,因为实体无法自我阅读。正确的吗?

我想解决的问题是。 ...在上面的示例中,Entity通过Doctrine填充,然后返回数据。因此我必须使用另一个类来填充实体。没有Doctrine,我知道可以做一些事情,比如从实体内部读取数据,即通过mysqli,然后直接或通过方法返回属性。换句话说,我是否绝对需要另一个位置(实体之外的类/函数/方法)来填充实体?

示例实体看起来像这样

class Pricing
{
    function getSerialization(){}

    /**
     * @var integer @Column(name="id", type="integer", nullable=false)
     *      @Id
     *      @GeneratedValue(strategy="IDENTITY")
     */
    protected $id;
    //etc, a typical Doctrine Entity
}

1 个答案:

答案 0 :(得分:2)

是的,实体类的实例可以自己阅读 但我想你的问题应该是:" Doctrine实体可以加载并自行阅读吗?" 。答案是否定的......

实体的加载由doctrine internals管理。如果您希望实体类加载自身,则意味着将EntityManager注入实体类。

这是一个坏主意,我quote @BryanM。他对另一个堆栈溢出问题的回答很好地解决了这个问题:

  

允许实体对象依赖实体管理器并不是一个好主意。它将实体与持久层联系起来,这是Doctrine 2专门试图解决的一个问题。依赖于实体管理器的最大麻烦在于,它使您的模型难以独立于数据库进行测试。

     

您可能应该依赖服务对象来处理依赖于实体管理器的操作。

这意味着您需要在外部处理加载实体。我仍然没有看到getSerialization的问题。它可以在Entity类中,可以在实体加载后使用吗?

如果您想立即加载和序列化,我建议您在其中注入存储库或实体管理器PricingService,并在其中定义执行所有操作的公共方法。例如:

<?php

use Application\Entity\Pricing;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;

class PricingService
{
    /**
     * @var EntityManager
     */
    protected $entityManager;

    /**
     * @param EntityManager $entityManager
     */
    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    /**
     * @return EntityRepository;
     */
    protected function getRepository()
    {
        return $this->entityManager->getRepository(`Application\Entity\Pricing`);
    }

    /**
     * @param $params
     * @return array 
     */
    public function findSerializedBy($params)
    {
        $pricing = $this->getRepository()->findOneBy($params);
        return $pricing->getSerialization();
    }
}

现在您可以直接使用您的PricingService:

$serializedPricing = $pricingService->findSerializedBy(array(
    'active' => true,
    'product_id' => (int) $this->id
));

您当然可以通过添加$classname的其他参数来概括您的服务。