まずはDoctrine\DBAL\Types\Type
クラスを拡張国のカスタムDBALタイプを登録する必要があります。
<?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;
}
}
このタイプは、4つの方法getName
、getSQLDeclaration
、convertToDatabaseValue
とconvertToPHPValue
を実装する必要があります。
- THRE最初のタイプ
- の名前を返す第二つ(SQL)データベース内の型宣言するためのものである(私は例で
text
を使用しますが、整数使用または有効な任意の他のできdoctrineデータベースタイプ)。
- 3番目のメソッドは、国オブジェクトをデータベース値(この場合はテキスト値)に変換します。
- 最後の方法は反対です。データベースからテキスト値を変換します。この場合、私は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;
Doctrine2 documentation chapter Custom Mapping Types
カスタムDBAL型のマッピング方法の詳細はこちらDoctrine 2 ORMまたはDBALだけを使用していますか? – edigu
こんにちは、私は教義2 ORMを使用していますが、将来私は教義2をサポートしますODM – user3549136