Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 覆盖条令2.6中特征属性的关联映射_Php_Symfony_Doctrine Orm_Doctrine_Symfony 3.3 - Fatal编程技术网

Php 覆盖条令2.6中特征属性的关联映射

Php 覆盖条令2.6中特征属性的关联映射,php,symfony,doctrine-orm,doctrine,symfony-3.3,Php,Symfony,Doctrine Orm,Doctrine,Symfony 3.3,先决条件: PHP7.1.8 Symfony 3.3.9 条令2.6.x-dev 我想知道是否有可能覆盖属性关联映射的inversedBy属性,该属性取自特征 我用作具体用户实体占位符的界面: ReusableBundle\modelnentranterface.php interface EntrantInterface { public function getEmail(); public function getFirstName(); public fu

先决条件:

  • PHP7.1.8
  • Symfony 3.3.9
  • 条令2.6.x-dev
我想知道是否有可能覆盖属性关联映射的
inversedBy
属性,该属性取自特征

我用作具体用户实体占位符的界面:

ReusableBundle\modelnentranterface.php

interface EntrantInterface
{
    public function getEmail();

    public function getFirstName();

    public function getLastName();
}
/**
 * @ORM\MappedSuperclass
 */
abstract class Entry
{
    /**
     * @var EntrantInterface
     *
     * @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="entries")
     * @ORM\JoinColumn(name="user_id")
     */
    protected $user;

    // getters/setters...
}
/**
 * @ORM\MappedSuperclass
 */
abstract class Timestamp
{
    /**
     * @var EntrantInterface
     *
     * @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="timestamps")
     * @ORM\JoinColumn(name="user_id")
     */
    protected $user;

    // getters/setters...
}
trait UserAwareTrait
{
    /**
     * @var EntrantInterface
     *
     * @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface")
     * @ORM\JoinColumn(name="user_id")
     */
    protected $user;

    // getter/setter...
}
  • 以下体系结构工作正常(需要创建实现
    entranterface
    User
    实体以及从
    AppBundle
    中的这些抽象类派生的所有其他实体):
  • ReusableBundle\Entity\Entry.php

    interface EntrantInterface
    {
        public function getEmail();
    
        public function getFirstName();
    
        public function getLastName();
    }
    
    /**
     * @ORM\MappedSuperclass
     */
    abstract class Entry
    {
        /**
         * @var EntrantInterface
         *
         * @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="entries")
         * @ORM\JoinColumn(name="user_id")
         */
        protected $user;
    
        // getters/setters...
    }
    
    /**
     * @ORM\MappedSuperclass
     */
    abstract class Timestamp
    {
        /**
         * @var EntrantInterface
         *
         * @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="timestamps")
         * @ORM\JoinColumn(name="user_id")
         */
        protected $user;
    
        // getters/setters...
    }
    
    trait UserAwareTrait
    {
        /**
         * @var EntrantInterface
         *
         * @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface")
         * @ORM\JoinColumn(name="user_id")
         */
        protected $user;
    
        // getter/setter...
    }
    
    ReusableBundle\Entity\Timestamp.php

    interface EntrantInterface
    {
        public function getEmail();
    
        public function getFirstName();
    
        public function getLastName();
    }
    
    /**
     * @ORM\MappedSuperclass
     */
    abstract class Entry
    {
        /**
         * @var EntrantInterface
         *
         * @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="entries")
         * @ORM\JoinColumn(name="user_id")
         */
        protected $user;
    
        // getters/setters...
    }
    
    /**
     * @ORM\MappedSuperclass
     */
    abstract class Timestamp
    {
        /**
         * @var EntrantInterface
         *
         * @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="timestamps")
         * @ORM\JoinColumn(name="user_id")
         */
        protected $user;
    
        // getters/setters...
    }
    
    trait UserAwareTrait
    {
        /**
         * @var EntrantInterface
         *
         * @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface")
         * @ORM\JoinColumn(name="user_id")
         */
        protected $user;
    
        // getter/setter...
    }
    
    并使用
    entranterface

  • 这就是我想要实现的-
    userawaretrit
    可以跨多个实体重用:
  • ReusableBundle\Entity\Traits\userawaretrit.php

    interface EntrantInterface
    {
        public function getEmail();
    
        public function getFirstName();
    
        public function getLastName();
    }
    
    /**
     * @ORM\MappedSuperclass
     */
    abstract class Entry
    {
        /**
         * @var EntrantInterface
         *
         * @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="entries")
         * @ORM\JoinColumn(name="user_id")
         */
        protected $user;
    
        // getters/setters...
    }
    
    /**
     * @ORM\MappedSuperclass
     */
    abstract class Timestamp
    {
        /**
         * @var EntrantInterface
         *
         * @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="timestamps")
         * @ORM\JoinColumn(name="user_id")
         */
        protected $user;
    
        // getters/setters...
    }
    
    trait UserAwareTrait
    {
        /**
         * @var EntrantInterface
         *
         * @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface")
         * @ORM\JoinColumn(name="user_id")
         */
        protected $user;
    
        // getter/setter...
    }
    
    在原则2.6中,如果我想使用超类并覆盖它的属性,我会这样做:

    /**
     * @ORM\MappedSuperclass
     * @ORM\AssociationOverrides({
     *     @ORM\AssociationOverride({name="property", inversedBy="entities"})
     * })
     */
    abstract class Entity extends SuperEntity
    {
        // code...
    }
    
    但是,如果我希望该实体使用
    userawaretrit
    并覆盖属性的关联映射

    /**
     * @ORM\MappedSuperclass
     * @ORM\AssociationOverrides({
     *     @ORM\AssociationOverride({name="user", inversedBy="entries"})
     * })
     */
    abstract class Entry
    {
        use UserAwareTrait;
        // code...
    }
    
    。。。然后运行
    php-bin/console-doctor:schema:validate
    我在控制台中看到这个错误:

    [条令\ORM\Mapping\MappingException]
    类“ReusableBundle\Entity\Entry”的名为“user”的字段重写无效

    是否有一个变通方法,我可以遵循,以达到预期的结果

  • 使用trait存储共享属性

  • 重写使用该特性的类中的关联映射或(可能)属性映射


  • 您必须在自己的代码中尝试这一点才能看到,但这是可能的

    作为实验,我重写了类中的一个特征,然后使用
    class\u uses()

    你可以在这里看到


    然而,条令注释仍然可能从trait本身而不是覆盖的方法中获取DocBlock,这就是为什么我不能给您一个明确的答案。你只需要试试看

    TL;DR您应该将访问修改器从
    受保护
    更改为
    专用
    。不要忘记,您将无法直接操作子类中的私有属性,并且需要一个getter

    出现异常的原因是
    AnnotationDriver
    中的错误(我相信,或行为异常)

    foreach ($class->getProperties() as $property) {
        if ($metadata->isMappedSuperclass && ! $property->isPrivate()
            ||
            ...) {
            continue;
        }
    
    它跳过了
    MappedSuperclass
    的所有非私有属性,让它们在子类解析时组成元数据。但是,当涉及到重写时,驱动程序尝试在
    MappedSuperclass
    级别执行此操作,它不记得该属性已被跳过,在元数据中找不到该属性并引发异常


    我在会议上作了详细的解释。您还可以在这里找到突出显示该案例的单元测试的链接

    我遇到了一个类似的问题,并通过重写其自身的属性来解决它:

    use UserAwareTrait;
    /**
     * @var EntrantInterface
     * @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface"inversedBy="entries")
     */
    protected $user;
    

    谢谢你的回答,这不是我需要的。我不想重写一个方法(我只需要在每个类中定义它,然后分别进行注释,这正是我希望避免的)。在方法体中没有什么可以重写的,只有getter和setter。我有一个类似的实现,但在我的例子中,使用这个特性的类不是
    MappedSuperclass
    。您是否尝试过删除
    抽象类条目上的
    @ORM\MappedSuperclass
    行?更重要的是:您尝试在不指定关系的情况下重写a关系(在本例中为
    ManyToOne
    。尝试:
    @ORM\AssociationOverrides({@ORM\AssociationOverride(name=“user”,ManyToOne=@ORM\ManyToOne(targetEntity=“ReusableBundle\Model\entranterface”,inversedBy=“entities”))
    。在最后一个代码块中,它是
    inversedBy=“entries”
    ,与原始代码相同,在第二个代码块中,它是
    inversedBy=“entities”
    …请仔细阅读,我想在多个实体中重复使用特征,因此没有机会在特征中覆盖它,inversedBy必须为每个实体具有不同的值是的,我的回答是覆盖每个实体中的特征属性,以设置适当的inversedBy