首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Symfony2 2/Doctrine2 2继承

Symfony2 2/Doctrine2 2继承
EN

Stack Overflow用户
提问于 2013-07-01 15:58:32
回答 2查看 1.4K关注 0票数 0

我试图在Doctrine 2中完成基本继承,但我遇到了几个主要问题。这样的任务不应该这么复杂。我们谈正事吧..。

我有三门课,BaseFoodType,饮料和零食。我的BaseFoodType有以下类定义:

代码语言:javascript
运行
复制
/** @ORM\MappedSuperclass */
class BaseFoodType {

    /**
     * @ORM\Column(type="integer", length=7)
     */
    public $budget = 0;
}

遵循教义网站:http://docs.doctrine-project.org/en/2.0.x/reference/inheritance-mapping.html的继承指南。

下面是生成我的实体之前子类的样子:

代码语言:javascript
运行
复制
namespace MySite\MainBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * MySite\MainBundle\Entity\EventDrink
 *
 * @ORM\Table(name="drink")
 * @ORM\Entity
 */
class Drink extends BaseFoodType {

    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="integer", length=5, nullable=true)
     */
    public $people_count;
}

build和Snack都继承了这个基类,但是当我试图使用“生成:实体”命令构建我的实体时,我遇到了许多问题。首先,Symfony在每个子类中插入一个私有的“预算”属性,以及getter和setter(这违背了目的继承)

代码语言:javascript
运行
复制
/**
 * @var integer
 */
private $budget;

/**
 * Set budget
 *
 * @param integer $budget
 */
public function setBudget($budget)
{
    $this->budget = $budget;

    return $this;
}

/**
 * Get budget
 *
 * @return integer 
 */
public function getBudget()
{
    return $this->budget;
}

第二,我犯了一个致命的错误:

致命错误:第197行C:\xampp\htdocs\MySite\src\MySite\MainBundle\Entity\Drink.php中对MySite\MainBundle\Entity\ line::$预算的访问级别必须是公共的(如MySite\MainBundle\Entity\BaseFoodType类中的那样)

我可能会将生成的属性公之于众,并在我的路上,但同样,这违背了继承的目的!

提前感谢您的任何见解。

EN

回答 2

Stack Overflow用户

发布于 2014-02-11 02:52:55

理论提供了一种方法来指定生成字段的可见性。不管是受保护的还是私人的。默认值是私有的。

问题是调用Doctrine的Symfony命令无法改变这一点。

创建标准Symfony命令的自己的子类将允许您对生成过程进行更多的控制。这可能对你有帮助。

代码语言:javascript
运行
复制
namespace Foo\Bundle\FooBundle\Command;

use Doctrine\Bundle\DoctrineBundle\Command as DC;
use Doctrine\ORM\Tools\EntityGenerator;

class GenerateEntitiesDoctrineCommand extends DC\GenerateEntitiesDoctrineCommand
{

    protected function configure()
    {
        parent::configure();
        $this->setName('foo:generate:entities');
    }

    /**
     * get a doctrine entity generator
     *
     * @return EntityGenerator
     */
    protected function getEntityGenerator()
    {
        $entityGenerator = new EntityGenerator();
        $entityGenerator->setGenerateAnnotations(true);
        $entityGenerator->setGenerateStubMethods(true);
        $entityGenerator->setRegenerateEntityIfExists(false);
        $entityGenerator->setUpdateEntityIfExists(true);
        $entityGenerator->setNumSpaces(4);
        $entityGenerator->setAnnotationPrefix('ORM\\');
        $entityGenerator->setFieldVisibility($entityGenerator::FIELD_VISIBLE_PROTECTED);

        return $entityGenerator;
    }
}

这做了两件事。它将属性可见性设置为受保护。这可以防止php错误。

$entityGenerator->setFieldVisibility($entityGenerator::FIELD_VISIBLE_PROTECTED);

它还将映射的超类中的注释复制到实体类中。

$entityGenerator->setGenerateAnnotations(true);

下面是一些示例代码,其中属性是从基类继承的,它们的可见性和注释正确地复制到继承类中。

代码语言:javascript
运行
复制
/** @ORM\MappedSuperclass */
class DataSuper {
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM\ManyToOne(targetEntity="Campaign", inversedBy="data")
     * @ORM\JoinColumn(name="campaign_id", referencedColumnName="id")
     * @Exclude
     */
    protected $campaign;

    /**
     * @ORM\Column(type="text", nullable=true, name="data")
     */
    protected $data;

    /**
     * @ORM\Column(type="datetime")
     */
    protected $createdDate;
}


/**
 * @ORM\Entity(repositoryClass="Foo\Bundle\FooBundle\Entity\DataRepository")
 * @ORM\Table(name="data")
 * @ExclusionPolicy("none")
 */
class Data extends DataSuper
{
}

生成数据类后,如下所示:

代码语言:javascript
运行
复制
class Data extends DataSuper
{

/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer", precision=0, scale=0, nullable=false, unique=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
protected $id;

/**
 * @var string
 *
 * @ORM\Column(name="data", type="text", precision=0, scale=0, nullable=true, unique=false)
 */
protected $data;

/**
 * @var \DateTime
 *
 * @ORM\Column(name="createdDate", type="datetime", precision=0, scale=0, nullable=false, unique=false)
 */
protected $createdDate;

/**
 * @var \Foo\Bundle\FooBundle\Entity\Campaign
 *
 * @ORM\ManyToOne(targetEntity="Foo\Bundle\FooBundle\Entity\Campaign", inversedBy="data")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="campaign_id", referencedColumnName="id", nullable=true)
 * })
 */
protected $campaign;


/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set data
 *
 * @param string $data
 * @return Data
 */
public function setData($data)
{
    $this->data = $data;

    return $this;
}

/**
 * Get data
 *
 * @return string 
 */
public function getData()
{
    return $this->data;
}

/**
 * Set createdDate
 *
 * @param \DateTime $createdDate
 * @return Data
 */
public function setCreatedDate($createdDate)
{
    $this->createdDate = $createdDate;

    return $this;
}

/**
 * Get createdDate
 *
 * @return \DateTime 
 */
public function getCreatedDate()
{
    return $this->createdDate;
}

/**
 * Set campaign
 *
 * @param \Foo\Bundle\FooBundle\Entity\Campaign $campaign
 * @return Data
 */
public function setCampaign(\Foo\Bundle\FooBundle\Entity\Campaign $campaign = null)
{
    $this->campaign = $campaign;

    return $this;
}

/**
 * Get campaign
 *
 * @return \Foo\Bundle\FooBundle\Entity\Campaign 
 */
public function getCampaign()
{
    return $this->campaign;
}
}

而且,一旦您这样做,表结构是正确的:

php app/console doctrine:schema:update --force

票数 3
EN

Stack Overflow用户

发布于 2013-07-01 16:56:26

抛出此异常是因为BaseFoodType::budget公共属性,doctrine:generate:entities在饮料/ Snack类中创建了私有属性,扩展BaseFoodType (这是不正确的,但到目前为止命令的工作方式)。

子类中的属性可见性只能是相同的级别或更多的自由度(私有->保护的->公共),但从来没有更多的限制。

doctrine:generate:entities在生成getter/setter时没有考虑超类的公共属性,因为带有公共属性的实现是不标准的。

因此,您必须手动调整生成的类。

我建议将私有/受保护的属性与getters和setter结合使用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17408757

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档