Symfony2+Doctrine: How to convert iso8859-1 to utf

2020-04-11 18:32发布

问题:

We're building a Symfony2 app that's using an Oracle database. All the data in the DB is encoded as WE8ISO8859P15 (iso-8859-1), and all the website is encoded as utf-8.

Is there any way to convert all the data received from the database to utf8, and all the data sent to the DB to iso-8859-1, instead of convert the website to iso8859-1? Maybe using a Doctrine event subscriber? If so, which events should I intercept?

回答1:

I solve a similar problem with a MSSQL instance for convert from utf8 to latin1 and viceversa. I do the following step:

  1. Define a custom DBAL Type
  2. Initialise on the boot Bundle method (i think you can do in the config.yml too)
  3. Use it as annotation on the entity field

This his the code:

DBAL CUSTOM TYPE

<?php
namespace Acme\DemoBundle\Doctrine\Type;

use Doctrine\DBAL\Types\StringType;
use Doctrine\DBAL\Platforms\AbstractPlatform;

class Utf8String 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');
    }
}

BUNDLE INITIALISATION

<?php

namespace Acme\DemoBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use Doctrine\DBAL\Types\Type;

class AcmeDemoBundle extends Bundle
{
    public function boot() {

        if (!Type::hasType('utf8string'))
        {
            Type::addType('utf8string', 'Acme\DemoBundle\Doctrine\Type\Utf8String');

            $em = $this->container->get('doctrine.orm.em_my_sqlserver_entity_manager');
            $conn = $em->getConnection();
            $conn->getDatabasePlatform()->registerDoctrineTypeMapping('Utf8String', 'utf8string');
        }
    }

}

AN EXAMPLE MAPPED ENTITY

<?php

namespace Acme\DemoBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 *
 * @ORM\Table(name="VEHICLE")
 * @ORM\Entity()
 */
class Vehicle
{

    /**
     * @ORM\Id
     * @ORM\Column(name="VEHICLE_NAME", type="utf8string", length=16, nullable=false)
     */
    private $name;


    /**
     * @var integer
     *
     * @ORM\Column(name="ID_VEHICLE", type="integer", nullable=true)
     */
    private $idVehicle;

....
}

Hope this help and hoping you find a better solutions too!!!



回答2:

You are able to set encoding of connection to your oracle db in config.yml. In your case you should set connection encoding to UTF-8 and Oracle should handle all conversion between UTF-8 (website) and iso-8859-1 (db) encoding. So putting this configuration in your config.yml should be enough:

doctrine:
    dbal:
        default_connection: oracle
        connections:
            oracle:
                driver:   %ora_database_driver%
                host:     %ora_database_host%
                port:     %ora_database_port%
                dbname:   %ora_database_name%
                user:     %ora_database_user%
                password: %ora_database_password%
                charset:  UTF8