У меня есть набор ключевых слов, которые передаются через JSON из БД (кодированный UTF-8), некоторые из которых могут иметь специальные символы, такие как é, è, ç и т. Д. Это используется как часть автокомплексора. Пример:
array('Coffee', 'Cappuccino', 'Café');
Я должен добавить, что массив, исходящий из БД, будет:
array('Coffee', 'Cappuccino', 'Café');
Но JSON кодирует как:
["coffee", "cappuccino", null];
Если я распечатаю их с помощью print_r (), они будут отображаться на веб-странице, кодированной UTF-8, но кафе появляется в виде «cafû, если используется текст / plain, если я хочу посмотреть на массив, используя print_r ($ array) ;Выход();.
Если я кодирую с помощью utf8_encode () перед кодировкой в JSON, он проходит через штраф, но то, что печатается на веб-странице, является «кафе», а не «кафе».
Также странно, но json_last_error () рассматривается как неопределенная функция, но json_decode () и json_encode () работают нормально.
Любые идеи о том, как заставить кодированные данные UTF-8 из базы данных вести себя одинаково на протяжении всего процесса?
EIDT: Вот функция PHP, которая захватывает ключевые слова и превращает их в один массив:
private function get_keywords() { global $db, $json; $output = array(); $db->query("SELECT keywords FROM listings"); while ($r = $db->get_array()) { $split = explode(",", $r['keywords']); foreach ($split as $s) { $s = trim($s); if ($s != "" && !in_array($s, $output)) $output[] = strtolower($s); } } $json->echo_json($output); }
Метод json :: echo_json просто кодирует, устанавливает заголовок и печатает его (для использования с Prototype)
EDIT: DB Метод подключения:
function connect() { if ($this->set['sql_connect']) { $this->connection = @mysql_connect( $this->set['sql_host'], $this->set['sql_user'], $this->set['sql_pass']) OR $this->debug( "Connection Error", mysql_errno() .": ". mysql_error()); $this->db = @mysql_select_db( $this->set['sql_name'], $this->connection) OR $this->debug( "Database Error", "Cannot Select Database '". $this->set['sql_name'] ."'"); $this->is_connected = TRUE; } return TRUE; }
Дополнительные обновления: Простой скрипт PHP, который я запускал:
echo json_encode( array("Café") ); // ["Caf\u00e9"] echo json_encode( array("Café") ); // null
Причиной может быть настройка текущего клиента. Простым решением может быть установка клиента с помощью mysql_query('SET CHARACTER SET utf8')
перед запуском запроса SELECT
.
Обновление (июнь 2014 года)
Расширение mysql устарело от PHP 5.5.0. В настоящее время рекомендуется использовать mysqli. Кроме того, при дальнейшем прочтении – вышеуказанный способ настройки набора клиентов следует избегать по причинам, включая безопасность .
Я не тестировал его, но это должно быть заменой ok:
$mysqli = new mysqli("localhost", "my_user", "my_password", "my_db"); if (!$mysqli->set_charset('utf8')) { printf("Error loading character set utf8: %s\n", $mysqli->error); } else { printf("Current character set: %s\n", $mysqli->character_set_name()); }
или с параметром подключения:
$conn = mysqli_connect("localhost", "my_user", "my_password", "my_db"); if (!mysqli_set_charset($conn, "utf8")) { # TODO - Error: Unable to set the character set exit; }
Кажется, что json_encode
строки, содержащие недопустимые символы. Вероятно, ваши данные UTF-8 не поступают в соответствующую форму из вашей базы данных.
Глядя на примеры, которые вы даете, моя дикая догадка заключается в том, что ваше соединение с базой данных не кодируется в кодировке UTF-8 и вместо этого служит символам ISO-8859-1.
Можете ли вы попробовать SET NAMES utf8;
после инициализации соединения?
Я попробовал свой пример кода, как это
[~]> cat utf.php <?php $arr = array('Coffee', 'Cappuccino', 'Café'); print json_encode($arr); [~]> php utf.php ["Coffee","Cappuccino","Caf\u00e9"] [~]>
Исходя из этого, я бы сказал, что если исходные данные действительно UTF-8, то json_encode работает просто отлично. Если это не так, то вот где вы получите нуль. Почему его нет, я не могу сказать, основываясь на этой информации.
Попробуйте отправить массив через эту функцию перед выполнением json_encode ():
<?php function utf8json($inArray) { static $depth = 0; /* our return object */ $newArray = array(); /* safety recursion limit */ $depth ++; if($depth >= '30') { return false; } /* step through inArray */ foreach($inArray as $key=>$val) { if(is_array($val)) { /* recurse on array elements */ $newArray[$key] = utf8json($inArray); } else { /* encode string values */ $newArray[$key] = utf8_encode($val); } } /* return utf8 encoded array */ return $newArray; } ?>
Взято из комментария на phpnet @ http://php.net/manual/en/function.json-encode.php .
Функция в основном зацикливается на элементах массива, возможно, вы сделали свой код utf-8 в самом массиве?
Моим решением для кодирования данных utf8 было:
$jsonArray = addslashes(json_encode($array, JSON_FORCE_OBJECT|JSON_UNESCAPED_UNICODE))