2013-03-11 110 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} 

希望幫助