Question

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);
}
Was it helpful?

Solution

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');
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top