2013-03-11 121 views
5

我使用zf2.1.3和doctrine 2.我试图在我的课程上提供信息,并意识到DoctrineModule\Stdlib\Hydrator\DoctrineObject不适用于带有下划线的字段,如cat_idDoctrine 2 Hydrator - 带下划线的字段

下面的例子:

/* namespace Application\Entity; */ 

class Foo 
{ 
    private $cat_id; 
    private $cat_name; 

    public function getCatId() 
    { 
     return $this->cat_id; 
    } 

    public function setCatName($name) 
    { 
     $this->cat_name = $name; 
     return $this; 
    } 

    public function getCatName() 
    { 
     return $this->cat_nome; 
    } 
} 

class Bar 
{ 
    private $id; 
    private $name; 

    public function getId() 
    { 
     return $this->id; 
    } 

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

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

/* namespace Application\Controller; */ 

use \DoctrineModule\Stdlib\Hydrator\DoctrineObject; 
public function indexAction() 
{ 
    $hydrator = new DoctrineObject($this->getEntityManager(), 'Application\Entity\Foo'); 
    $foo = $hydrator->hydrate(array('cat_name' => 'Frank Moraes'), new Foo()); 
    \Zend\Debug\Debug::dump($foo, 'Foo Hydrator'); 

    $hydrator = new DoctrineObject($this->getEntityManager(), 'Application\Entity\Bar'); 
    $bar = $hydrator->hydrate(array('name' => 'Frank Moraes'), new Bar()); 
    \Zend\Debug\Debug::dump($inscrit, 'Bar Hydrator'); 
} 

此代码返回如下:

Foo Hydrator 
object(Application\Entity\Foo) 
    private 'cat_id' => null 
    private 'cat_name' => null 

Bar Hydrator 
object(Application\Entity\Foo) 
    private 'id' => null 
    private 'name' => 'Frank Moraes' 

所以我的问题是:为什么主义保湿不与在它强调的领域工作? 我该如何做这项工作?

谢谢!

编辑

很抱歉的很长一段时间没有答案。在我的工作中,没有人可以访问!

我试过如下:

$hydrator = new DoctrineObject($this->getEntityManager(), 'Application\Entity\Foo', false); 

对于我贴在这里,这false参数正常工作的例子。

但是,当我绑定表单上的类时,它不起作用!

有人有线索吗?

+0

我会发布此问题上的原则谷歌的用户群。 – 2013-03-11 01:31:45

+0

这是因为默认的inflector不处理下划线。您需要自行调整它或在https://github.com/doctrine/DoctrineModule/issues上发布关于Doctrine模块问题跟踪器的问题 我现在可以告诉您,我没有时间查看虽然现在进入它。 – Ocramius 2013-03-11 03:05:22

+0

我在https://github.com/doctrine/DoctrineModule/issues/190上发布了这个问题 – vinigarcia87 2013-03-13 01:14:21

回答

9

后这几个月已经问过,但我一直在刚才检查DoctrineObject水化的源代码,我觉得这是发生了什么事情:

默认情况下,除非你构建DoctrineObject水化byValue标记为false,水合器将以byValue模式工作。这意味着它试图从你想要保湿的值中构造getter和setter方法名称,并且通过在字段名称上调用ucfirst并预先设置get/set来实现。

因此,例如,你有cat_name,所以它会尝试吸气剂方法getCat_name,这显然是不正确的。

您有4个选择,然后:

  • 答:camelCase你的变量名
  • B:设置byValue为false(这样,它试图直接访问的变量),虽然我认为你可能不得不将变量公开在这种情况下......我不知道可见度将如何影响它,因为我以前没有尝试过]
  • C:使用不同的水化Strategy
  • D:只是有奇怪的getter和setter名称,如getCat_name(请不要这样做)。
+2

感谢您发布这个!我通过将我的变量名称更改为camelCase来解决此问题。很高兴知道这个问题的原因! – vinigarcia87 2013-10-07 20:14:16

+0

没问题!很高兴它有帮助。 – 2013-10-08 02:28:11

+0

对于选项** B **,您不应该将属性设置为public,因为它会[打破延迟加载](http://stackoverflow.com/questions/4090609/how-can-public-fields-break-lazy-装载功能于主义-2)。如果你想访问你的属性没有getter和setter你应该实现[魔术'__get'和'__set'](http://php.net/manual/en/language.oop5.magic.php) – Wilt 2015-03-07 15:22:44

0

快速和肮脏...

foreach ($form as $key => $value) { 
     while ($pos = strrpos($key,'_')) {         
      $key = substr_replace($key, '', $pos, 1); 
      $capitalized = strtoupper($key[$pos]); 
      $key[$pos] = $capitalized;         
     } 
     $data[$key] = $value; 
    } 
0

你仍然可以使用这一招:

/** @ORM\Column(name="column_name", type="string") */ 
protected $columnName; 

function get(...); 
function set($columnName){$this->columnName = $columnName} 

希望帮助