Декодировать управляющие символы Юникода в строке JSON

Ситуация

Я импортирую огромные файлы JSON в базу данных. Он содержит поля, которые были заполнены пользователями с помощью онлайн-редактора wysiwyg. Это позволяло им также вставлять специальные символы, обычно скопированные из документа MS Word.

Проблема

После декодирования файла JSON пара специальных символов пропущена. Оказывается, большинство из них — это, например, управляющие символы Unicode † который представляет собой символ U+0086.

Пример

<?php
$json = '{"test": "start \u0086 end"}';
$decoded = json_decode($json);
echo $decoded->test . PHP_EOL;

Вывод:

start  end

Ожидаемый результат:

start † end

Временное исправление

На данный момент я применил это грязное исправление, но я все еще ищу более элегантный способ замены всех символов Юникода.

protected static function replaceUnicodeCharacters(&$string)
{
    $replace = [
        "\u0086" => "†",
        "\u00b0" => "°",
        "\u0093" => "“",
        "\u0094" => "”",
        "\u0091" => "‘",
        "\u0092" => "’",
        "\u009c" => "œ",
        "\u00f6" => "ö",
        "\u00f9" => "ù",
        "\u00ad" => "­",
        "\u0096" => "–",
        "\u00fb" => "û",
        "\u00a0" => " ",
        "\u0085" => "…",
        "\u00ab" => "«",
        "\u00bb" => "»",
        "\u008c" => "Œ",
        "\u00c0" => "À",
        "\u00ff" => "ÿ",
        "\u00fc" => "ü",
    ];

    $string = str_ireplace(array_keys($replace), array_values($replace), $string);
}

person Bram Verstraten    schedule 01.08.2019    source источник
comment
Ни одному из моих тестовых браузеров не удалось отобразить версию этого символа «UTF-8» на fileformat.info/info/unicode/char/0086/browsertest.htm правильно, только десятичный/шестнадцатеричный переход HTML работает правильно.   -  person misorude    schedule 01.08.2019


Ответы (2)


0x86 при интерпретации как Windows-1252 равно †. Вам просто не хватает шага кодирования:

$decoded->test = mb_convert_encoding($decoded->test, "Windows-1252", "UTF-8");
echo '<html><meta charset="Windows-1252">';
echo $decoded->test . PHP_EOL;
person daxim    schedule 01.08.2019
comment
Для меня это приводит к start � end. Повторить кодировку невозможно, так как я использую консольное приложение. - person Bram Verstraten; 01.08.2019
comment
Затем установите соответствующую кодировку консоли. Похоже, вы настроили его для отображения UTF-8, но я пытаюсь объяснить, что ваши данные находятся в Windows-1252. - person daxim; 01.08.2019

EDIT: PHP Unicode в JSON

Я надеюсь, что, по крайней мере, это поможет...

person ya_Bob_Jonez    schedule 01.08.2019
comment
Это дает NULL в PHP 7.3 и Uncaught JsonException: синтаксическая ошибка в коде оболочки php: 1 с включенным JSON_THROW_ON_ERROR - person Maxime Launois; 01.08.2019
comment
Ладно, извини. Просто пытался помочь. :( Возможно, это потому, что этот символ не поддерживается большинством браузеров. PHP не может правильно отображать крестик. D: Наверное. - person ya_Bob_Jonez; 01.08.2019