Unescaped "json" Doctrine type

By default all json Doctrine types escape slashes and Unicode characters before storing strings in the database.

By default all json Doctrine types escape slashes and Unicode characters before storing strings in the database.

If we want to avoid this (for example to be able to use native MySQL Full-Text Search functions) we need to override original convertToDatabaseValue() method for the json type we are going to use, and pass JSON_UNESCAPED_SLASHES and/or JSON_UNESCAPED_UNICODE options to json_encode() function.

For example in case of most basic json type this might look like this:

# src/Doctrine/DBAL/Types/UnescapedJsonType.php
namespace App\Doctrine\DBAL\Types;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\ConversionException;
use Doctrine\DBAL\Types\JsonType;
use const JSON_ERROR_NONE;

/**
 * Type generating json objects values with unescaped Unicode characters.
 */
class UnescapedJsonType extends JsonType
{
    /**
     * {@inheritdoc}
     */
    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        if (null === $value) {
            return null;
        }

        $encoded = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

        if (JSON_ERROR_NONE !== json_last_error()) {
            throw ConversionException::conversionFailedSerialization($value, 'json', json_last_error_msg());
        }

        return $encoded;
    }
}

To use our new class:

# config/packages/doctrine.yaml
doctrine:
    dbal:
        # ...
        types:
            json: App\Doctrine\DBAL\Types\UnescapedJsonType