Декодировать строку в кириллицу в PHP

У меня есть такая строка:

Óâàæàåìûé êëèåíò!

И хочу расшифровать его в кириллицу. Я уже пытаюсь декодировать с помощью mb_convert_encoding, но не не получить должного результата.

$string = 'Óâàæàåìûé êëèåíò!';
$stringEncode = mb_detect_encoding($string);

$result = mb_convert_encoding($string, "CP1251", $stringEncode);

echo $result //????????? ??????!

//Case with auto detect encoding return the same result
$result = mb_convert_encoding($string, "CP1251");

echo $result //????????? ??????!

Я пытаюсь использовать разные кодировки символов, но всегда получаю неправильный результат.

Правильный результат должен быть:

Уважаемый клиент!

Внимание! Я пытаюсь использовать онлайновые сервисы для кодирования текущей строки и получения нужный результат. Нить не оборвана. Кажется, что PHP не может определить кодировку и преобразовать текущую строку в кириллицу.

Спасибо за любую помощь!

ОБНОВЛЕНИЕ:

<Сильный> bin2hex выход : c393c3a2c3a0c3a6c3a0c3a5c3acc3bbc3a920c3aac3abc3a8c3a5c3adc3b22120c387c3a0c3a2c3b2c3b0c3a020c3adc3a5c3aec3a1c3b5c3aec3a4c3a8c3acc3ae20c3a2c3adc3a5c3b1c3b2c3a820c3acc3a8c3adc3a8c3acc3a0c3abc3bcc3adc3bbc3a920c3afc3abc3a0c3b2c3a5c3a620c3afc3ae20c3a7c3a0c3a9c3acc3b320c3a220c3b0c3a0c3a7c3acc3a5c3b0c3a52036343120c3b0c3b3c3a1c3abc3a5c3a92e20c384c3abc3bf20c3aec3afc3abc3a0c3b2c3bb20c3a2c3aec3b1c3afc3aec3abc3bcc3a7c3b3c3a9c3b2c3a5c3b1c3bc20c3abc3a8c3b7c3adc3bbc3ac20c3aac3a0c3a1c3a8c3adc3a5c3b2c3aec3ac20707572652e636f6d2e7275

«Откуда взялась эта строка изначально?» - первоначально я получаю ответ от Api в формате json, затем я использую utf8_encode (если я не использую эту функцию, json_decode возвращает null) и, наконец, json_decode возвращает мне массив данных:

[
    'status'         => '1',
    'last_date'      => '15.05.2018 10:00:17',
    'last_timestamp' => '1526353217',
    'send_date'      => '15.05.2018 10:00:05',
    'send_timestamp' => '1526353205',
    'phone'          => '79270212817',
    'cost'           => '6.24',
    'sender_id'      => 'PURE',
    'status_name'    => 'Äîñòàâëåíî',
    'message'        => 'Óâàæàåìûé êëèåíò!'

];

person Odin Thunder    schedule 16.05.2018    source источник
comment
Каковы необработанные байты этой строки? echo bin2hex($string). Откуда изначально взялась эта строка?   -  person deceze♦    schedule 16.05.2018
comment
обновить вопрос   -  person Odin Thunder    schedule 16.05.2018
comment
Мне кажется, что JSON находится в какой-то экзотической кодировке. Вместо того, чтобы делать utf8_encode, а затем пытаться справиться с последствиями, выясните, что такое кодировка JSON, и преобразуйте ее из этой кодировки в UTF-8, прежде чем использовать json_decoding. Лучший способ выяснить кодировку — спросить источник (любые заголовки HTTP…?). В противном случае откройте его в текстовом редакторе с помощью команды «Переоткрыть с помощью кодировки…» или как там это называется в вашем текстовом редакторе, пробуя разные кодировки, пока не найдете ту, в которой текст выглядит так, как ожидалось.   -  person deceze♦    schedule 16.05.2018
comment
Я попытаюсь получить исходную кодировку из ответа API. Большое спасибо, я не копал таким образом, я просто копирую строку из json_decoded и пытаюсь преобразовать ее. PS: Не понимаю ребят, которые просто голосуют без объяснения причин, какой смысл?   -  person Odin Thunder    schedule 16.05.2018
comment
@deceze, как bin2hex поможет разобраться в этом случае? (Я могу использовать это для оригинального ответа API)   -  person Odin Thunder    schedule 16.05.2018
comment
@deceze, большое спасибо, исправлю )))   -  person Odin Thunder    schedule 16.05.2018
comment
Текст состоит из байтов. То, как эти байты интерпретируются, приводит к символам, которые вы видите на экране. Просто видя символы на экране, вы понятия не имеете, что такое байты, и, следовательно, понятия не имеете, неверны ли байты или интерпретация неверна. Поэтому всегда смотрите на необработанные байты при решении проблем с кодировкой. Здесь пример показал, что вы имеете дело с символами Unicode, а не с неверно истолкованными CP-байтами, поэтому можно сделать вывод, что какой-то предыдущий шаг кодирования уже пошел не так.   -  person deceze♦    schedule 16.05.2018


Ответы (2)


В соответствии с советом deceze я получаю кодировку для своего исходного ответа API (windows-1251). Затем я переписываю свой код «подготовки к json_decode» и получаю правильный результат.

//Replace this:
$contents = utf8_encode($response);
//To this:
$contents = mb_convert_encoding($response, 'utf-8', 'windows-1251');

$result   = json_decode($contents);

Уведомление! Этот utf8_encode преобразует ISO-8859-1 в UTF-8 и если мы передадим в эту функцию данные с другой кодировкой (в моем случае это windows-1251), то получим неожиданный результат. Большое спасибо @mulquin и @deceze, которые помогли мне решить эту проблему.

PS: Всегда проверяйте кодировку исходных данных, не повторяйте моих ошибок :)

person Odin Thunder    schedule 16.05.2018

Я думаю, вы можете быть правы в своем предположении, что PHP не может обрабатывать некоторые символы в этой строке. Я сделал следующее устранение неполадок и не смог найти проблему. Кажется, mb_check_encoding возвращает, что преобразование должно быть возможным, но оно почему-то не работает...

Возможно, вам придется выполнить преобразование вручную: PHP Convert Windows-1251 to UTF 8

<?php

$utf8_string = 'Óâàæàåìûé êëèåíò!';
$cp1251_string = 'Уважаемый клиент!';

$utf8_detect = mb_detect_encoding($utf8_string, 'UTF-8');
$cp1251_detect = mb_detect_encoding($cp1251_string, 'CP1251');

$utf8_to_cp1251_check = mb_check_encoding($utf8_string, $cp1251_detect);
$cp1251_to_utf8_check = mb_check_encoding($cp1251_string, $utf8_detect);

$utf8_to_cp1251 = mb_convert_encoding($utf8_string, $cp1251_detect);
$cp1251_to_utf8 = mb_convert_encoding($cp1251_string, $utf8_detect);

$utf8_to_cp1251_icon = iconv( "UTF-8","CP1251//TRANSLIT", $utf8_string);

var_dump($utf8_string);
var_dump($cp1251_string);

echo PHP_EOL;

var_dump($utf8_detect);
var_dump($cp1251_detect);

echo PHP_EOL;

var_dump($utf8_to_cp1251_check);
var_dump($cp1251_to_utf8_check);

echo PHP_EOL;

var_dump($utf8_to_cp1251);
var_dump($cp1251_to_utf8);

echo PHP_EOL;

var_dump($utf8_to_cp1251_icon);

Выход

string(32) "Óâàæàåìûé êëèåíò!" 
string(32) "Уважаемый клиент!" 

string(5) "UTF-8" 
string(12) "Windows-1251" 

bool(true) 
bool(true) 

string(17) "????????? ??????!" 
string(32) "Уважаемый клиент!" 

string(18) "???ae????? ??????!"
person mulquin    schedule 16.05.2018