Why is this PHP call to json_encode silently failing - inability to handle single quotes?

You need to set the connection encoding before executing queries. How this is done depends on the API you are using to connect:

  • call mysql_set_charset("utf8") if you use the old, deprecated API.
  • call mysqli_set_charset("utf8") if you use mysqli
  • add the charset parameter to the connection string if you use PDO and PHP >= 5.3.6. In earlier versions you need to execute SET NAMES utf8.

When you obtain data from MySQL any text will be encoded in "client encoding", which is likely windows-1252 if you don't configure it otherwise. The character that is causing your problem is the "curly quote", seen as 92 in the hex dump, which confirms that the mysql client is encoding text in windows-1252.

Another thing you might consider is pass all text through utf8_encode, but in this case it wouldn't produce the correct result. PHP's utf8_encode converts iso-8859-1-encoded text. In this encoding \x92 is a non-printable control character, which would be converted into a non-printable control character in utf-8. You could use str_replace("\x92", "'", $input) to fix the problem for this particular character, but if there's any chance there will be any other non-ascii characters in the database you'll want to have the client use UTF-8.


What I've had to do in the past to json_encode on text with utf8 characters is

json_encode( utf8_encode( $s ) );

and in some cases

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

the utf8_encode() to handle special characters (note, that's Encode, not Decode)

the htmlspecialchars() depending on how you mean to use the JSON string, you may be able to leave this out

and finally, json_encode() to get your JSON packet.

Since you want to json_encode an object, you would need to call utf8_encode() on each text part first, or write a simple recursive utf8_encode(). For your example case, this would do:

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

I would like to refer you about this issue, on link I suggest you use a json_encode wrapper like this :

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;
}

And after define these function you can use it direct,

echo safe_json_encode($response);

Tags:

Php

Json