2014-11-12 2 views
0

В моей компании у нас есть веб-сервис zu, который отправляет данные из очень старых проектов в довольно новые. В старых проектах выполняется PHP4.4, у которого нет метода json_encode. Таким образом, мы использовали класс PEAR Service_JSON. http://www.abeautifulsite.net/using-json-encode-and-json-decode-in-php4/PHP4: метод Json_encode, который принимает многобайтовые символы

Сегодня я узнал, что этот класс может не дело с несколькими байтовых символов, поскольку он широко использует ord() для того, чтобы получить charcodes из строки и заменить символы. Реализация mb_ord() отсутствует, даже в новых версиях PHP. Он также использует $ string {$ index} для доступа к символу в индексе, я не совсем уверен, поддерживает ли это многобайтовые символы.

//Excerpt from encode() method 

// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT 
      $ascii = ''; 
      $strlen_var = $this->strlen8($var); 

      /* 
      * Iterate over every character in the string, 
      * escaping with a slash or encoding to UTF-8 where necessary 
      */ 
      for ($c = 0; $c < $strlen_var; ++$c) { 

       $ord_var_c = ord($var{$c}); 
       //Here comes a switch which replaces chars according o their hex code and writes them to $ascii 

мы называем

$Service_Json = new Service_JSON(); 
$data = $Service_Json->encode('Marktplatz, Hauptstraße, Endingen'); 
echo $data; //prints "Marktplatz, Hauptstra\u00dfe, Endinge". The n is missing 

Мы решили эту проблему, создав другой WebService, который принимает сериализованы массивы и возвращает json_encoded строку. Эта служба работает на современном махине, поэтому она использует PHP5.4. Но это «решения довольно неудобно, и я должен искать лучший друг. Кто-нибудь есть идеи?

Описание проблемы

немецких умляуты заменяются правильно. Но тогда строка покроя в конце потому что ога возвращает неправильные символы.. mb_strlen() ничего не меняет, он дает такую ​​же длину, как STRLEN в этом случае.

Входная строка была «Marktplatz, Hauptstraße, Endingen», п в конце было отрезанный. ß был правильно закодирован до \ u00df. Для каждого Umlaut он разрезает еще один символ в конце.

Возможно также, что причина в нашей старой кодировке базы данных, но сама замена работает правильно, поэтому я думаю, что это метод ord().

+0

Я только что загрузил модуль 'Services_JSON' и протестировал его с вашими входными данными. Работал отлично. Я получил ту же кодировку '\ u00df', но я не пропустил окончательный' n'. Что вы получаете, если вы выполняете 'strlen ($ your_input_string)'? –

+0

Он возвращает длину 33. Если это правильно, наша кодировка базы данных является неисправной. mb_check_encoding() возвращает false, а mb_detect_encoding() возвращает utf-8. – Corni

+0

Если длина равна 33, это означает, что 'ß' вводится как однобайтовый символ' 0xDF', а не UTF-8-представление '0xC39F'. Интересно, может ли это быть проблемой? –

ответ

1

коллега обнаружил, что

mb_strlen($var, 'ASCII'); 

решает эту проблему. У нас была более старая версия lib, которая использовала простой mb_strlen. Это исправление, похоже, делает то же самое, что и ваш mb_convert_encoding();

Проблема решена сейчас. Большое спасибо за Вашу помощь!

Смежные вопросы