Значения в UTF-8 кодируются как NULL в JSON - PullRequest
9 голосов
/ 12 сентября 2010

У меня есть набор ключевых слов, которые передаются через JSON из БД (в кодировке UTF-8), некоторые из которых могут иметь специальные символы, такие как é, è, ç и т. Д. Это используется как часть автоматическогозавершивший.Пример:

array('Coffee', 'Cappuccino', 'Café');

Я должен добавить, что массив в том виде, в котором он исходит из БД, будет:

array('Coffee', 'Cappuccino', 'Café');

Но JSON кодирует как:

["coffee", "cappuccino", null];

ЕслиЯ печатаю их с помощью print_r (), они хорошо отображаются на веб-странице в кодировке UTF-8, но caf выглядит как «café», если используется text / plain, если я хочу посмотреть на массив с помощью print_r ($ array);exit ();.

Если я закодирую с использованием utf8_encode () перед кодированием в JSON, все пройдет хорошо, но на веб-странице будет напечатано «cafà ©», а не «café».

Также странно, но 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)

EDИТ: Метод подключения к БД:

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

Ответы [ 5 ]

11 голосов
/ 15 октября 2012

Причиной может быть текущая настройка символов клиента.Простым решением может быть установка клиента с mysql_query('SET CHARACTER SET utf8') перед выполнением запроса SELECT.

Обновление (июнь 2014)

Расширение mysql устарелопо состоянию на PHP 5.5.0.Теперь рекомендуется использовать mysqli.Кроме того, после дальнейшего прочтения - вышеупомянутого способа установки клиентского набора следует избегать по причинам, включающим безопасность .

Я не проверял это, но это должно быть хорошей заменой:

$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;
}
3 голосов
/ 12 сентября 2010

json_encode, кажется, отбрасывает строки, содержащие недопустимые символы.Вполне вероятно, что ваши данные UTF-8 не поступают в правильной форме из вашей базы данных.

Глядя на приведенные вами примеры, я могу предположить, что ваша база данных connection не являетсяКодируется UTF-8 и служит вместо символов ISO-8859-1.

Можете ли вы попробовать SET NAMES utf8; после инициализации соединения?

3 голосов
/ 12 сентября 2010

Я попробовал ваш пример кода вот так

[~]> cat utf.php 
<?php
$arr = array('Coffee', 'Cappuccino', 'Café');
print json_encode($arr);
[~]> php utf.php 
["Coffee","Cappuccino","Caf\u00e9"]
[~]>

Исходя из этого, я бы сказал, что если исходные данные действительно UTF-8, то json_encode работает просто отлично. Если это не так, то здесь вы получите ноль. Почему нет, я не могу сказать, основываясь на этой информации.

1 голос
/ 12 сентября 2010

Попробуйте отправить ваш массив через эту функцию перед выполнением 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 на самом массиве?

0 голосов
/ 26 февраля 2016

Мое решение для кодирования данных utf8 было:

$jsonArray = addslashes(json_encode($array, JSON_FORCE_OBJECT|JSON_UNESCAPED_UNICODE))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...