为什么这个PHP调用json_encode会无声地失败 - 无法处理单引号?

ryb*_*ome 43 php json

我有一个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
)
Run Code Online (Sandbox Code Playgroud)

通过调用json_encode()此对象来回显结果会导致以下结果:

{
    "ID": "12981",
    "post_title": null,
    "post_parent": "0",
    "post_date": "2012-01-31 12:00:51"
}
Run Code Online (Sandbox Code Playgroud)

我假设单引号的东西导致json_encode窒息,但我不知道需要什么格式来逃避.有任何想法吗?

编辑:修复了代码示例中的不匹配问题.我正在运行PHP 5.3.8版

EDIT2:在编码对象后,我直接执行了以下操作:

echo json_last_error() == JSON_ERROR_UTF8;
Run Code Online (Sandbox Code Playgroud)

这打印1,这意味着发生以下错误:"格式错误的UTF-8字符,可能编码错误".json_last_error()

编辑3:调用utf8_decode()帖子标题导致以下内容:"校友?晚餐即将来临".这些数据是从MySQL数据库中提取的 - 特别是帖子标题是一个UTF-8编码的文本字段.也许这个单引号编码不正确?问题是,我有一个SQL GUI应用程序,它正确显示在那里.

Jon*_*oni 57

您需要在执行查询之前设置连接编码.如何完成取决于您用于连接的API:

  • 打电话mysql_set_charset("utf8"),如果你使用的时候,弃用API.
  • mysqli_set_charset("utf8")如果您使用mysqli,请致电
  • 如果使用PDO和PHP> = 5.3.6,请将charset参数添加到连接字符串.在早期版本中,您需要执行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.

  • 或者等效的mysqli_set_charset($ link,"utf8")如果您正在使用它们. (4认同)
  • @MarcoMarsala修复了.mysqli没有被弃用的顺便说一句 (2认同)

Umb*_*lla 25

我过去用utf8字符对json_encode进行json_encode所做的就是

json_encode( utf8_encode( $s ) );
Run Code Online (Sandbox Code Playgroud)

在某些情况下

json_encode( htmlspecialchars( utf8_encode( $s ) ) );
Run Code Online (Sandbox Code Playgroud)

utf8_encode()来处理特殊字符(注意,这是编码,而不是解码)

htmlspecialchars()取决于您使用JSON字符串的意思,您可以将其保留

最后,json_encode()获取您的JSON数据包.

由于你想要json_encode一个对象,你需要先在每个文本部分调用utf8_encode(),或者写一个简单的递归utf8_encode().对于您的示例,这将做:

function myEncode($o) {
    $o->title = utf8_encode($o->title);
    return json_encode($o);
}
Run Code Online (Sandbox Code Playgroud)

  • 然后,我想人们必须做一些像`array_walk_recursive($ s,'utf8_encode'); (2认同)

Jho*_*man 7

我有同样的问题,而JSON编码从ODBC查询结果的PHP数组,我的服务器的OBC配置'en_US.819',是一个生产服务器,所以我甚至无法触摸它!

我试过的时候:

echo json_encode($GLOBALS['response'], true);
Run Code Online (Sandbox Code Playgroud)

'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); 
  }
Run Code Online (Sandbox Code Playgroud)

现在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",....
Run Code Online (Sandbox Code Playgroud)

这解决了我的问题.


man*_*706 6

我想向您介绍这个问题,在链接上, 我建议您使用像这样的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;
}
Run Code Online (Sandbox Code Playgroud)

在定义了这些功能之后,您可以直接使用它,

echo safe_json_encode($response);
Run Code Online (Sandbox Code Playgroud)