【问题标题】:Doctrine2 + Symfony2: Can Doctrine just map properties using direct access?Doctrine2 + Symfony2:Doctrine 可以直接使用直接访问来映射属性吗?
【发布时间】:2014-10-15 08:50:34
【问题描述】:

我想将 Doctrine2 用于 ORM。我有一个非常简单的类和一个 XML 元数据映射。

一般的想法是,通过 ORM 和类的通信应该只通过 get/set 方法发生,而不会将类的内部(例如私有属性名称)暴露给 orm。

<?php
namespace Foo\Bar\Entity;

class Test {

    private $name_property = null;

    public function setName($name)
    {
        $this->name_property = $name;
    }

    public function getName()
    {
        return $this->name_property;
    }

}

还有映射

<?xml version="1.0" encoding="UTF-8" ?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
    http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

<entity name="Foo\Bar\Entity\Test">
    <field name="Name" type="text" />
</entity>

我认为这个设置应该在从/到数据库中取消/序列化对象时调用 getName() 和 setName($string_argument) 方法。

显然不是。

Property Foo\Bar\Entity\Test::$Name does not exist 

我以为 Doctrine2 总是使用 get/set 方法与对象进行交互,因为它试图直接访问属性。

Doctrine 真的可以只映射类字段属性并总是尝试直接访问它们吗?如果我的 set() 方法包含业务逻辑(例如字符串参数验证),因此不能直接通过 Doctrine2 设置属性怎么办?我想我在这里遗漏了一些基本的东西。

提前感谢您的帮助!

【问题讨论】:

    标签: symfony orm doctrine-orm


    【解决方案1】:

    属性 Foo\Bar\Entity\Test::$Name 不存在

    $name 永远不会在您的 Test 类中声明。并且尝试从外部访问 $name_property 是不可能的,因为它被声明为私有。你也不需要它。出于这个原因,那里有 Set 和 Get 方法。

    Doctrine 真的可以只映射类字段属性并总是尝试吗 直接访问它们?如果我的 set() 方法包含业务怎么办 逻辑

    我认为像您发布的那样,将 Doctrine Models 与他们的 setter 和 getter 一起保留是一个明智的想法。 将您自己的类中的业务逻辑留在 ORM 之外。 ORM 的使命是成为代码和数据库之间的数据库抽象层,因此您可以使用 OOP 完成所有操作。

    在 symfony 文档中对此进行了更好的描述: http://symfony.com/doc/current/book/doctrine.html 在最佳实践书第 4 章中,您可以阅读“组织您的业务逻辑”: http://symfony.com/doc/download-best-practices-book/

    【讨论】: