Подтвердить что ты не робот

Почему этот вызов PHP для json_encode бесшумно терпит неудачу - неспособность обрабатывать одиночные кавычки?

У меня есть объект stdClass с именем $post, который при сбрасывании через print_r() возвращает следующее:

stdClass Object (
    [ID] => 12981
    [post_title] => Alumnus' Dinner Coming Soon
    [post_parent] => 0
    [post_date] => 2012-01-31 12:00:51
)

Повторение результата вызова json_encode() на этом объекте приводит к следующему:

{
    "ID": "12981",
    "post_title": null,
    "post_parent": "0",
    "post_date": "2012-01-31 12:00:51"
}

Я предполагаю, что что-то с одной цитатой вызывает json_encode, чтобы задохнуться, но я не знаю, какой формат нужен, чтобы избежать этого. Любые идеи?

EDIT: Исправлено несоответствие в примерах кода. Я запускаю PHP версии 5.3.8

EDIT2: сразу после кодирования объекта я сделал следующее:

echo json_last_error() == JSON_ERROR_UTF8;

Отпечатано 1, что означает, что произошла следующая ошибка: "Недопустимые символы UTF-8, возможно, неправильно закодированные". json_last_error()

EDIT3: Вызов utf8_decode() в заголовке сообщения привел к следующему: "Ученик" Ужин "Скоро". Эти данные извлекаются из базы данных MySQL - в частности, заголовок сообщения представляет собой текстовое поле, кодированное UTF-8. Может быть, эта одиночная кавычка неправильно закодирована? Дело в том, что у меня есть приложение с графическим интерфейсом SQL, и оно выглядит правильно.

4b9b3361

Ответ 1

Перед выполнением запросов вам необходимо установить кодировку соединения. Как это сделать, зависит от API, который вы используете для подключения:

  • вызов mysql_set_charset("utf8"), если вы используете старый, устаревший API.
  • вызов mysqli_set_charset("utf8"), если вы используете mysqli
  • добавьте параметр charset в строку подключения, если вы используете PDO и PHP >= 5.3.6. В более ранних версиях вам нужно выполнить SET NAMES utf8.

Когда вы получаете данные из MySQL, любой текст будет закодирован в "клиентской кодировке", что, скорее всего, windows-1252, если вы не настроите его иначе. Характер, вызывающий вашу проблему, - это "кулисная цитата", которая рассматривается как 92 в шестнадцатеричном дампе, что подтверждает, что клиент mysql кодирует текст в windows-1252.

Еще одна вещь, которую вы можете рассмотреть, - передать весь текст через utf8_encode, но в этом случае он не даст правильного результата. PHP utf8_encode преобразует iso-8859-1 -кодированный текст. В этой кодировке \x92 является непечатаемым управляющим символом, который будет преобразован в непечатаемый управляющий символ в utf-8. Вы можете использовать str_replace("\x92", "'", $input), чтобы исправить проблему для этого конкретного символа, но если есть вероятность, что в базе данных будут какие-либо другие символы, отличные от ascii, вы хотите, чтобы клиент использовал UTF-8.

Ответ 2

То, что мне нужно было сделать в прошлом для json_encode по тексту с символами utf8,

json_encode( utf8_encode( $s ) );

и в некоторых случаях

json_encode( htmlspecialchars( utf8_encode( $s ) ) );

the utf8_encode() для обработки специальных символов (обратите внимание, что Encode, а не Decode)

htmlspecialchars() в зависимости от того, как вы хотите использовать строку JSON, вы можете оставить это вне

и, наконец, json_encode(), чтобы получить ваш пакет JSON.

Поскольку вы хотите json_encode для объекта, вам нужно сначала вызвать utf8_encode() для каждой текстовой части или написать простой рекурсивный utf8_encode(). Для примера вашего примера:

function myEncode($o) {
    $o->title = utf8_encode($o->title);
    return json_encode($o);
}

Ответ 3

У меня была такая же проблема, в то время как JSON, кодирующая php-массив из результатов запроса ODBC, мой сервер OBC настроен с 'en_US.819', является производственным сервером, поэтому я даже не могу его коснуться!!

когда я попытался:

echo json_encode($GLOBALS['response'], true);

Где "respose" представляет собой массив с результатами, он работает так, как предполагалось, так как не существует причудливого char, если это так, json_encode не возвращает пустой.

Решение?.... UTF кодирует результаты при извлечении строк из запроса:

$result = odbc_exec($conn, $sql_query);
$response = array();
while( $row = odbc_fetch_array($result) ) { 
     $json['pers_identificador'] = $row['pers_identificador'];
     $json['nombre_persona'] = utf8_encode( $row['nombre_persona'] );
     $json['nombre_1'] = utf8_encode($row['nombre_1'] );
     $json['nombre_2'] = utf8_encode($row['nombre_2'] );
     array_push($response, $json); 
  }

Теперь json_encode работает!!!, результирующая строка выглядит примерно так:

{"page_id":300,"max_rows":"100","cant_rows":"12897","datos":
  [{"pers_identificador":"301","cedula":"15250068","interno_1":"178202","interno_2":"","nombre_persona":"JOSE JUAN PANDOLFO ZAGORODKO","nombre_1":"JOSE","nombre_2":"JUAN",....

Это исправило мою проблему.

Ответ 4

Я хотел бы сообщить вам об этой проблеме, по ссылке, которую я предлагаю вам использовать упаковщик json_encode, например:

function safe_json_encode($value){
    if (version_compare(PHP_VERSION, '5.4.0') >= 0) {
        $encoded = json_encode($value, JSON_PRETTY_PRINT);
    } else {
        $encoded = json_encode($value);
    }
    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            return $encoded;
        case JSON_ERROR_DEPTH:
            return 'Maximum stack depth exceeded'; // or trigger_error() or throw new Exception()
        case JSON_ERROR_STATE_MISMATCH:
            return 'Underflow or the modes mismatch'; // or trigger_error() or throw new Exception()
        case JSON_ERROR_CTRL_CHAR:
            return 'Unexpected control character found';
        case JSON_ERROR_SYNTAX:
            return 'Syntax error, malformed JSON'; // or trigger_error() or throw new Exception()
        case JSON_ERROR_UTF8:
            $clean = utf8ize($value);
            return safe_json_encode($clean);
        default:
            return 'Unknown error'; // or trigger_error() or throw new Exception()
    }
}


function utf8ize($mixed) {
    if (is_array($mixed)) {
        foreach ($mixed as $key => $value) {
            $mixed[$key] = utf8ize($value);
        }
    } else if (is_string ($mixed)) {
        return utf8_encode($mixed);
    }
    return $mixed;
}

И после определения этих функций вы можете использовать его напрямую,

echo safe_json_encode($response);

Ответ 5

Вы можете попробовать установить кодировку в конфигурации базы данных:

'charset' => 'utf8',
'driver_options' => array(
    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
)