问题
I'm working with a legacy big ball of mud that uses a latin1
database but works with utf8
strings. Each time the application reads or writes to database, it decodes or encodes by hand and stores utf8
encoded strings in the latin1
database.
When writing, it does something like:
$value = utf8_encode("Iñtërnâtiônàlizætiøn")
mysql_query("INSERT INTO table (key) VALUES ($value)")
So the stored value is Iñtërnâtiônà lizætiøn
And when reading:
$result = mysql_query("SELECT key FROM table")
$value = utf8_decode($result) // Wich results on "Iñtërnâtiônàlizætiøn" again
How can I manage the same database using Doctrine 2 and respecting that strange behaviour?
The following code will work as expected when used in my Entity
, but I'm looking for a cleaner and DRY solution.
public function setKey($value)
{
$this->key = utf8_encode($value);
}
public function getKey()
{
return utf8_decode($this->key);
}
回答1:
You could create your own custom "string" type and override it's class in Doctrine\DBAL\Types\Type
. Type::convertToDatabaseValue
and Type::convertToPHPValue
would be what you want to override.
<?php
use Doctrine\DBAL\Types\StringType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
class Utf8StringType extends StringType
{
/**
* {@inheritdoc}
*/
public function convertToDatabaseValue($value, AbstractPlatform $p)
{
// convert from utf8 to latin1
return mb_convert_encoding($value, 'ISO-8859-1', 'UTF-8');
}
/**
* {@inheritdoc}
*/
public function convertToPHPValue($value, AbstractPlatform $p)
{
// convert from latin1 to utf8
return mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1');
}
}
Then put the type into Doctrine with a new name or replace the string type:
<?php
\Doctrine\DBAL\Types\Type::addType('utf8string', 'Utf8StringType');
// replace the default string type
\Doctrine\DBAL\Types\Type::overrideType('string', 'Utf8StringType');
来源:https://stackoverflow.com/questions/19112284/forcing-encoding-decoding-with-doctrine-2