Php JSON字段中对象的Getter

Php JSON字段中对象的Getter,php,json,symfony,orm,doctrine,Php,Json,Symfony,Orm,Doctrine,我有两个实体: class Opponent { ... ... ... } class Process { /** * @var array * * @ORM\Column(name="answers_in_related_questionnaires", type="json", nullable=true) */ private $answersInRelatedQuestionnaires = [];

我有两个实体:

class Opponent
{
  ...
  ...
  ...
}

class Process 
{

    /**
     * @var array
     * 
     * @ORM\Column(name="answers_in_related_questionnaires", type="json", nullable=true)
     */
    private $answersInRelatedQuestionnaires = [];

    .
    .        
    . 

}
我在现场回答了与目标对手相关的问题

"opponent": {
 "id":1088,
 "name":"Inora Life Versicherung"
}
我想在实体过程中编写一个getter,它不仅从对手那里获取id和name两个值,而且还获取整个实体对手。大概是这样的:

private function getOpponent() : Opponent
{
    $id = $this->answersInRelatedQuestionnaires['opponent']['id'];
    return $entityManager->getRepository(Opponent::class)->find($id)
}

我已经读到,在实体中使用实体管理器不是一个好主意。我的问题有哪些解决方案?我可以在流程实体中使用流程存储库吗?

您不应该在实体中插入实体管理器,这是一种非常糟糕的做法,违反了类之间关注点的分离。但如果您确实需要,您确实可以在您的实体中注入实体管理器

良好实践:

创建一个
模型/流程
类,并在其中包含与模型相关的任何功能。条令实体不是模型类。在
Model/Process
中,您可以插入实体管理器和您需要的任何其他服务

编辑:通过创建
模型/流程
类,我的意思是在
/src
文件夹中的
模型
目录中创建一个名为
流程
的类。类的路径将是:
/src/Model/Process
。当然,目录或类的名称可以由任何内容来定义,但这是一个典型的约定。您的模型类应该负责您的所有业务逻辑,例如模型的验证等。这确实会使您的代码结构更加复杂,但从长远来看,对于大型项目来说,这将是一种享受。您还需要一个
模型/ProcessManager
来在不同的情况下(例如,从数据库、用户表单等加载时)正确填充流程模型当然,最终这都是复杂性和可持续性之间的权衡问题

关于Symfony中的模型,可以找到一种有趣的方法,它主要适用于大型项目

备选方案:

如果仅在加载实体后才访问
对手
属性,则可以使用加载后生命周期回调来正确设置
对手
属性。这是一个不错的做法:

use Doctrine\Common\Persistence\Event\LifecycleEventArgs;

/**
 * @ORM\Entity()
 * @ORM\HasLifecycleCallbacks()
 */
class Product
{
    // ...
    private $opponentObject;

    /**
     * @ORM\PostLoad
     */
     public function onPostLoad(LifecycleEventArgs $args){
         $em = $args->getEntityManager();

         $id = $this->answersInRelatedQuestionnaires['opponent']['id'];
         $this->opponentObject = $em->getRepository(Opponent::class)->find($id);

     }

     public function getOpponent() {
         return $this->opponent;

     }
} 
最后,如果您真的想将实体管理器注入到您的实体中,您可以通过自动连线通过依赖项注入来实现这一点:

use Doctrine\ORM\EntityManagerInterface;

class Process
{
    private $em;

    public function __contruct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }
    ....
}

实体之间是否存在任何关系?也许你应该发布你的实体结构和你想要达到的目标。是的,有很多关系。整个结构非常复杂。我想实现,用一个方法$process->gethatcher()获取整个对手对象;因为我们看不到实体结构,我认为实现这一点的最佳方法是使用原则关联/关系->关联/关系和JSON字段?恐怕不可能。不,我不想注入实体管理器。我知道,这是一个非常糟糕的做法。我发现onPostLoad的解决方案很有趣。但是,您对模型/流程的定义是什么?我不明白。你能详细解释一下吗?如果我用$this->getdoctor()->getRepository(Process::class)->find(2000000)获取数据,onPostLoad的解决方案是有效的;但是如果我使用查询生成器$qb=$this->createQueryBuilder('p')->select('p')->where('p.id=:processId')->setParameter('processId',2000000)获取数据,则不起作用;编辑我的答案,以便更好地解释模型/流程建议。这是一个更复杂的解决方案。