我想实现一个新的学说数据类型(http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html)。
我已经实施了一个国家/地区服务,它通过适配器从任何库加载国家/地区数据知道我有以下实现:
<?php
interface CountryInterface;
interface Address
{
public function setCountry(CountryInterface $country);
public function getCountry() : CountryInterface;
}
?>
所以,我想做的是 - 制作一个CountryType
,将Country
对象转换为特定的字符串值(使用的字段将通过OptionClass
设置,例如:Alpha2 ,Alpha3,IsoNumber)。
我的问题是,doctrine只允许通过classname进行数据类型映射,因此我无法实现工厂来加载所有需要的依赖项。
我希望这是可以理解的。
问候
答案 0 :(得分:1)
首先,您需要为扩展 2-sample test for equality of proportions with continuity correction
data: cbind(x, n - x)
X-squared = 27.161, df = 1, p-value = 1.872e-07
alternative hypothesis: two.sided
95 percent confidence interval:
0.02727260 0.05918556
sample estimates:
prop 1 prop 2
0.07580011 0.03257103
类的国家/地区注册自定义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
,但您也可以使用整数或任何其他有效的doctrine数据库类型)。 在我的示例中,我假设也允许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,
)
)
)
文件中的bootstrap上设置服务:
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);
}
中映射自定义DBAL类型