有没有更好的方法来处理Doctrine代理对象

A.D*_*.D. 6 php mysql symfony doctrine-orm

我有两个与一对一关系相关联的类.

class Client {
    ...
    /**
     * @ORM\OneToOne(targetEntity="ClientInfo")
     * @ORM\JoinColumn(name="id", referencedColumnName="client_id")
     */
    private $info;
    ...
    public function doSomething() {
        if (!$this->getInfo() instanceof ClientInfo) {
            return false;
        }
        return $this->getInfo()->doSomething();
    }
    ...
}

class ClientInfo {
    ...
    /**
     * @ORM\Id
     * @ORM\OneToOne(targetEntity="Client")
     * @ORM\JoinColumn(name="client_id", referencedColumnName="id")
     */
    private $client;
    ...
    public function doSomething() {
        return 'something';
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

这些类使用Doctrine加载数据库内容.当数据库中有数据时,它工作正常.但是如果没有ClientInfo数据,我会引发一个\ Doctrine\ORM\EntityNotFoundException.

所以我更改了doSomething()方法以考虑到这一点.

    public function doSomething() {
        if (!$this->getInfo() instanceof ClientInfo) {
            return false;
        }
        try {
            return $this->getInfo()->doSomething();
        } catch (\Doctrine\ORM\EntityNotFoundException $e) {
            return false;
        }
    }
Run Code Online (Sandbox Code Playgroud)

但它对我来说不合适,因为它与学说联系在一起.我试图修改我的单元测试以添加代理对象的模拟,但它也感觉不对.

有没有更好的方法呢?

编辑1

我遵循Nico Kaag的建议,但它没有改变任何东西.

我的Client类中的构造函数如下所示:

public function __construct() {
    $this->info = new ClientInfo();
}
Run Code Online (Sandbox Code Playgroud)

如果我在使用Doctrine检索我的对象后执行$ this-> info的var_dump ,这就是我得到的.

object(Proxies\__CG__\MyBundle\Entity\ClientInfo)[444]
  public '__initializer__' => 
    object(Closure)[461]
  public '__cloner__' => 
    object(Closure)[462]
  public '__isInitialized__' => boolean false
  private 'client' (MyBundle\Entity\ClientInfo) => string '21055' (length=5)
  ...
Run Code Online (Sandbox Code Playgroud)

编辑2

我终于改变了我的所作所为.我删除了try..catch块并更改了查询以从数据库中检索对象.现在,我强制查询在Client对象的同时检索ClientInfo对象.

这样,我可以相信我的测试,如果我忘记同时查询两个对象,我将有一个例外提醒它.

Jas*_*ngh 2

看我为你准备了课程。

use Doctrine\ORM\Mapping AS ORM;

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

    /**
     * @ORM\OneToOne(targetEntity="Entities\client_info", inversedBy="client")
     * @ORM\JoinColumn(name="client_info_id", referencedColumnName="id", unique=true)
     */
    private $clientInfo;
}
Run Code Online (Sandbox Code Playgroud)
use Doctrine\ORM\Mapping AS ORM;

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

    /**
     * @ORM\OneToOne(targetEntity="Entities\client", mappedBy="clientInfo")
     */
    private $client;
}
Run Code Online (Sandbox Code Playgroud)

试试这个,你不会遇到这样的问题。

另外,我还使用了基数一对一的双向关系,父级连接 0:1*-(父级可选),请参见图表。

ER图

建议:使用 ORM 设计器工具来设计和提取实体类。