首先,您需要註冊您的自定義DBAL類型擴展Doctrine\DBAL\Types\Type
類國家:
<?php
namespace Application\DBAL\Types;
use Application\Resource\Country;
use Application\Service\CountryService;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\ConversionException;
use Doctrine\DBAL\Types\Type;
use InvalidArgumentException;
class CountryType extends Type
{
const NAME = 'country';
/**
* Country service
*/
protected $countryService;
/**
* @return string
*/
public function getName()
{
return self::NAME;
}
/**
* {@inheritdoc}
*/
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return $platform->getDoctrineTypeMapping('text');
}
/**
* {@inheritdoc}
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
if($value === null){
return null;
}
if ($value instanceof Country) {
return (string) $value;
}
throw ConversionException::conversionFailed($value, self::NAME);
}
/**
* {@inheritdoc}
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if($value === null){
return null;
}
$country = $this->countryService->getCountry($value);
if(! $country instanceof Country){
throw ConversionException::conversionFailed($value, self::NAME);
}
return $country;
}
/**
* Set country service
*
* @var CountryService $service
*/
public function setCountryService ($service){
$this->countryService = $service;
}
}
這種類型需要實現四個方法getName
,getSQLDeclaration
,convertToDatabaseValue
和convertToPHPValue
。
- THRE第一個該類型
- 第二個是在(SQL)類型聲明數據庫(我在這個例子中使用
text
返回名稱,但你也可以使用整數或任何其他有效的學說數據庫類型)。
- 第三種方法將您的國家對象轉換爲數據庫值(因此在這種情況下爲文本值)。
- 最後一種方法正好相反;它轉換來自數據庫的文本值。在這種情況下,我只是實例化Country類並將數據庫值傳遞給構造函數。您需要在您的類構造函數中添加自定義邏輯。
在我的例子中,我假設null
值也是允許的。
你的國家類的簡單版本看起來是這樣的:
<?php
namespace Application\Resource;
class Country{
protected $value;
/**
* Magic stringify to cast country object to a string
*/
public function __toString(){
return $value;
}
/**
* Constructor method
*/
public function construct($value){
$this->value = $value
// set other properties...
}
// setters and getters...
}
這是給你值是否應該alpha2
/alpha3
/country_name
或任何你想在數據庫中可見。你應該以某種方式在構造函數方法中使用其他屬性填充另一個國家。我把這部分留給你。
現在,您需要註冊您的自定義的國家類型,這樣的教義將使用它:
'doctrine' => array(
//...
'configuration' => array(
'orm_default' => array(
Application\DBAL\Types\CountryType::NAME => Application\DBAL\Types\CountryType::class,
)
)
)
而且你可以在應用程序上的引導您的服務設置Module.php
文件:
/**
* @param EventInterface|MvcEvent $event
* @return void
*/
public function onBootstrap(EventInterface $event)
{
$application = $event->getApplication();
$eventManager = $application->getEventManager();
$eventManager->attach(MvcEvent::EVENT_BOOTSTRAP, array($this, 'initializeCountryType');
}
/**
* @param MvcEvent $event
*/
public function initializeCountryType(MvcEvent $event)
{
$application = $event->getApplication();
$serviceManager = $application->getServiceManager();
//get your country service from service manager
$countryService = $serviceManager->getCountryService();
$countryType = \Doctrine\DBAL\Types\Type::getType('country');
$countryType->setCountryService($countryService);
}
現在你可以在任何實體定義中使用您的國家類型如下:
/**
* @var string
* @ORM\Column(type="country", nullable=true)
*/
protected $country;
閱讀更多關於如何映射自定義DBAL類型Doctrine2 documentation chapter Custom Mapping Types
您是使用Doctrine 2 ORM還是僅使用DBAL? – edigu
嗨,此刻我使用了主義2 ORM,但是在將來我還會支持主義2 ODM – user3549136