2012-05-27 110 views
2

這是我原來的問題一個後續問題: Best strategy for migrating mysql enums to doctrine entities with symfony2?如何使用doctrine和symfony2自定義枚舉數據類型將枚舉值保存到數據庫?

我已經成功地添加枚舉數據類型此處的說明:http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/cookbook/mysql-enums.html 更具體我使用的溶液2使用後者部分在哪裏創建的基地EnumType類,然後擴展它想:

<?php 
namespace CP\AdminBundle\DataTypes; 

class EnumContactBasicGender extends EnumType 
{ 
    protected $name = 'EnumContactBasicGender'; 
    protected $values = array('m','f'); 

} 

我EnumType類的樣子:

<?php 
namespace CP\AdminBundle\DataTypes; 

use Doctrine\DBAL\Types\Type; 
use Doctrine\DBAL\Platforms\AbstractPlatform; 

abstract class EnumType extends Type 
{ 
    protected $name; 
    protected $values = array(); 

    public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform) 
    { 
     $values = array_map(function($val) { return "'".$val."'"; }, $this->values); 

     return "ENUM(".implode(", ", $values).") COMMENT '(DC2Type:".$this->name.")'"; 
    } 

    public function convertToPHPValue($value, AbstractPlatform $platform) 
    { 
     return $value; 
    } 

    public function convertToDatabaseValue($value, AbstractPlatform $platform) 
    { 
     if (!in_array($value, $this->values)) { 
      throw new \InvalidArgumentException("Invalid enum value given: '".$this->value."' for enum: '".$this->name."'"); 
     } 
     return $value; 
    } 

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

然後我註冊了我的枚舉是這樣的:

<?php 

namespace CP\AdminBundle; 
use Doctrine\DBAL\Types\Type; 
use Symfony\Component\HttpKernel\Bundle\Bundle; 

class CPAdminBundle extends Bundle 
{ 

public function boot() 
    { 
     $em = $this->container->get('doctrine.orm.entity_manager'); 
     Type::addType('EnumContactBasicGender', 'CP\AdminBundle\DataTypes\EnumContactBasicGender'); 
     Type::addType('EnumContactBasicType', 'CP\AdminBundle\DataTypes\EnumContactBasicType'); 
     $em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('EnumContactBasicGender','EnumContactBasicGender'); 
     $em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('EnumContactBasicType','EnumContactBasicType'); 
    } 
} 

當我運行命令./app/console學說:生成:實體CP它的作品!它創建我的新枚舉數據類型的實體,它創建的getter和setter方法沒有問題,我的實體之一是這樣的:

<?php 
namespace CP\AdminBundle\Entity; 
use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\ArrayCollection; 


/** 
* CP\AdminBundle\Entity\ContactBasic 
* 
* @ORM\Table(name="contacts_basics") 
* @ORM\Entity(repositoryClass="CP\AdminBundle\Entity\ContactBasicRepository") 
*/ 
class ContactBasic 
{ 
    /** Field #1 (contacts_id) **/ 
    /** 
    * @var integer $contacts_id 
    * @ORM\Column(type="integer",nullable=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $contacts_id; 
    /** enum ('m','f') **/ 
    /** 
    * @ORM\Column(type="EnumContactBasicGender",nullable=false) 
    */ 
    private $gender; 
    /** enum ('non-customer','customer','blacklisted') **/ 
    /** 
    * @ORM\Column(type="EnumContactBasicType",nullable=false) 
    */ 
    private $type; 

     /** more omitted properties here **/ 

    /** 
    * Set gender 
    * 
    * @param EnumContactBasicGender $gender 
    */ 
    public function setGender(\EnumContactBasicGender $gender) 
    { 
     $this->gender = $gender; 
    } 

    /** 
    * Get gender 
    * 
    * @return EnumContactBasicGender 
    */ 
    public function getGender() 
    { 
     return $this->gender; 
    } 
    /** 
    * Set type 
    * 
    * @param EnumContactBasicType $type 
    */ 
    public function setType(\EnumContactBasicType $type) 
    { 
     $this->type = $type; 
    } 

    /** 
    * Get type 
    * 
    * @return EnumContactBasicType 
    */ 
    public function getType() 
    { 
     return $this->type; 
    } 

     /** more omitted setters and getters here **/ 
} 

當我創建一個固定裝載機我的問題來了,我不知道如何設置任何枚舉值,讓他們保存到數據庫中,到目前爲止我的燈具裝載機類看起來是這樣的:

<?php 
namespace CP\AdminBundle\DataFixtures\ORM; 

use Doctrine\Common\DataFixtures\FixtureInterface; 
use Doctrine\Common\Persistence\ObjectManager; 
use CP\AdminBundle\Entity\ContactBasic; 
use CP\AdminBundle\DataTypes\EnumContactBasicGender; 
use CP\AdminBundle\DataTypes\EnumContactBasicType; 


class ContactBasicLoader implements FixtureInterface 
{ 
    public function load(ObjectManager $manager) 
    { 


     $contact = new ContactBasic(); 
     // $contact->setGender(new EnumContactBasicGender()); 
     $contact->setGender('m'); 

     // $contact->setType(new EnumContactBasicType()); 
     $contact->setType('customer'); 

     $manager->persist($contact); 
     $manager->flush(); 




    } 
} 

當我運行./app/console學說:燈具:負載我得到出現以下錯誤:

Catchable Fatal Error: Argument 1 passed to CP\AdminBundle\Entity\ContactBasic::setGender() must be an instance of EnumContactBasicGender, string given 

但如果我像上面的註釋行通過類,我也會得到一個錯誤。

有人可以請解釋我需要如何設置所需的值?

回答

1

我面臨的一個非常類似的問題,我通過在XXXEnumType類中添加值,但是公共的和靜態的同一陣列,這樣我在一個地方的內容規定解決我的枚舉,訪問它從任何地方和foreach它:)

但首先,檢查如果你添加my_foo_type在app/config/config。陽明:

# Doctrine Configuration 
doctrine: 
    dbal: 
     driver: %database_driver% 
     host:  %database_host% 
     port:  %database_port% 
     dbname: %database_name% 
     user:  %database_user% 
     password: %database_password% 
     charset: UTF8 
     types: 
      my_foo_type:  use XXX\DBAL\XXXEnumType 
     mapping_types: 
      enum: string 

<?php 
namespace XXX\DBAL; 

class XXXEnumType extends EnumType 
{ 
    protected $name = 'enum_xxx'; 
    protected $values = array('first', 'second', 'last'); 

    public static $static_name = 'enum_xxx'; 
    public static $static_values = array('first', 'second', 'last'); 

    public function getValues() 
    { 
     return $this->values; 
    } 
} 

和在我的項目在其他地方我可以這樣做:

use XXX\DBAL\XXXEnumType; 

foreach (XXXEnumType::$static_values as $value) 
{ 
    //do some stuff 
} 

希望它能幫助,

Linuxatico

+1

我認爲這有幫助,我一直在處理這個爲期4天,我想我會做什麼,這可能是最簡單的就是把我的枚舉看作字符串,並且一旦我通過重新編碼我的遺留應用程序隱蔽那些領域通過MySQL枚舉回來,只是忘記使用symfony命令行來更新我的數據庫模式,我只需要自己做! – MikeGA

+1

以我發佈的方式,枚舉被作爲字符串處理,並附加控件,如果插入的字符串與指定的字符串不同,則會引發錯誤 – linuxatico

1

原則沒有完全支持枚舉。枚舉類型看起來PRO,但沒有人用這種方式玩枚舉。解決方法是使用整數值在實體中設置少數靜態變量,並將枚舉字段設置爲整數類型。

有了您的問題,我會改變性別的二傳手:

  • 沒有方法的參數類型,然後將字符串傳遞一個簡單的字符串
  • 建立objec
  • 分配enumObject到實體的枚舉。

問候, 最大

相關問題