在Symfony / Doctrine

时间:2016-06-20 19:23:56

标签: php doctrine-orm doctrine symfony

我有一个Status表,用作标识/标记其他表中的状态的参考示例:

|  id   |   status   |
|-------|------------|
|  1    | Active     |
|  2    | Disabled   |
|  3    | Admin Only |
|  4    | Archived   |

我正在尝试在用户实体的isEnabled()函数中使用这些值。

 public function isEnabled() {

    $statusObj = $this->status;
    $statusValue = $statusObj->getStatus();

    if( $statusValue  != "Active" ){
        return false;
    }

    // Simply persisting true works
     return true;
}

使用此功能,它当前正在登录,我收到一个非对象错误。

错误:在非对象上调用成员函数getStatus()

看看调试,$ status似乎是一个代理对象,而不是我的Status对象,但似乎找不到任何东西可以从这里指出正确的方向。

User.orm.yml

AppBundle\Entity\User:
type: entity
table: user
indexes:
    fk_user_status1_idx:
        columns:
            - status_id
id:
    id:
        type: integer
        nullable: false
        options:
            unsigned: false
            comment: 'user Primary Key'
        id: true
        generator:
            strategy: IDENTITY
fields:
   # ....

manyToOne:
    status:
        targetEntity: Status
        cascade: {  }
        joinColumns:
            status_id:
                referencedColumnName: id
        orphanRemoval: false
manyToMany:
    roles:
        targetEntity: Role
        joinTable:
            name: user_has_role
            joinColumns:
                user_id:
                    referencedColumnName: id
            inverseJoinColumns:
                role_id:
                    referencedColumnName: id
lifecycleCallbacks: {  }

我尝试在User.orm.yml文件中更改fetch:状态,使其值为LAZY和EAGER,但都没有改变任何内容。

我试着让这篇文章简明扼要,所以如果我错过了任何重要的细节,请告诉我。

***更新***

我没有根据Many To One - Unidirectional Relatioinship设置映射/反转选项。我现在删除了“null”生成的值,因此状态与链接的文档相匹配。状态表和实体不以任何方式包含对用户的引用。

在我的IDE中运行debug时,我发现isEnabled()被调用两次... isEnabled()的第一次调用看起来完美无缺。 $ statsObj是==代理对象,当我调用$ statusObj-> getStatus()时,我看到它按预期返回“Active”。然后该函数返回true,调试器第二次跳回到isEnabled()。第二次运行isEnabled()我的用户对象为NULL。经过几个小时的努力,我的大脑试图找出为什么isEnabled()运行两次......最后我发现第一次运行是登录,第二次是在验证通过后的重定向期间。事实证明,整个问题是$ this->状态从未添加到Serialize / Unserialize函数中,因此在Unseralize之后,当调用inEnabled以验证它失败时,status属性为null。

解决方案远离所描述的问题,除非任何人有任何建议让这对另一个人有用我只会投票给删除。

2 个答案:

答案 0 :(得分:2)

由于延迟加载机制,Doctrine将您的关系包装在代理中。直接访问$this->status时,您将获得该代理对象。

请尝试使用getter:

public function isEnabled() {
    if( $this->getStatus()->getStatus() != "Active" ){
        return false;
    }
    ...
}

这看起来有点滑稽,但$this->getStatus()为您提供状态实体,而额外的getStatus()会询问状态实体的字段“状态”。

答案 1 :(得分:1)

您尚未发布您的状态实体代码,但您可能需要更改:

manyToOne:
    status:
        targetEntity: Status
        cascade: {  }
        orphanRemoval: false
          inversedBy: value_in_Status
        joinColumn:
            name: status_id
            referencedColumnName: id

请注意,您的“joinColumns”不是“joinColumn”。