12

I am reading from database with some text in Hebrew and trying to json_encode it. if i print_r the results i get:

Array
(
    [0] => Array
        (
            [value] => 88
            [text] => כיתה א'
            [parent_id] => 1
            [level] => 1
        )

    [1] => Array
        (
            [value] => 89
            [text] => כיתה ב'
            [parent_id] => 1
            [level] => 1
        )

    [2] => Array
        (
            [value] => 91
            [text] => כיתה ג'
            [parent_id] => 1
            [level] => 1
        )

)

while the json_encode shows:

[{"value":"88","text":null,"parent_id":"1","level":"1"},{"value":"89","text":null,"parent_id":"1","level":"1"},{"value":"91","text":null,"parent_id":"1","level":"1"}]

i belive it's because my text from the database contains a ( ' ) mark. tried various combination of stripslashes or real_escape_string none have helped.

NullUserException
  • 77,975
  • 25
  • 199
  • 226
eric.itzhak
  • 14,702
  • 26
  • 83
  • 137
  • It's not the `'` quote. It's most likely that your text encoding is not UTF-8. Or which charset do the database tables have? – mario Nov 15 '11 at 21:11
  • What character encoding are you using? The issue definitely looks to be with the missing ', it looks like you need to clean up the data from the db by encoding it to UTF-8 – Bob Gregor Nov 15 '11 at 21:11
  • json_encode only works with utf-8 strings according to the docs. check the output of `json_last_error()`. http://php.net/json-last-error. utf8 encode your strings before calling json_encode. – Frank Farmer Nov 15 '11 at 21:12
  • 1
    This is definitely encodable: http://codepad.org/Q6oKBDFg – NullUserException Nov 15 '11 at 21:13
  • possible duplicate of [json_encode is returning NULL?](http://stackoverflow.com/questions/1972006/json-encode-is-returning-null) – mario Nov 15 '11 at 21:16
  • [{"value":"88","text":"\u00eb\u00e9\u00fa\u00e4 \u00e0'","parent_id":"1","level":"1"},{"value":"89","text":"\u00eb\u00e9\u00fa\u00e4 \u00e1'","parent_id":"1","level":"1"},{"value":"91","text":"\u00eb\u00e9\u00fa\u00e4 \u00e2'","parent_id":"1","level":"1"}], is this valid? can i decode it with JS? – eric.itzhak Nov 15 '11 at 21:23

6 Answers6

22

json_encode expects strings in the data to be encoded as UTF-8.

Convert them to UTF-8 if they aren't already:

$results = array_map(function($r) {
  $r['text'] = utf8_encode($r['text']);
  return $r;
}, $results);
echo json_encode($results);
phihag
  • 245,801
  • 63
  • 407
  • 443
  • now it printed : [{"value":"88","text":"\u00eb\u00e9\u00fa\u00e4 \u00e0'","parent_id":"1","level":"1"},{"value":"89","text":"\u00eb\u00e9\u00fa\u00e4 \u00e1'","parent_id":"1","level":"1"},{"value":"91","text":"\u00eb\u00e9\u00fa\u00e4 \u00e2'","parent_id":"1","level":"1"}] is this how it's suppoused to be? im not suppoused to see it as text? – eric.itzhak Nov 15 '11 at 21:20
  • 1
    @eric.itzhak Yes, that is valid JSON. If you parse it again, the Unicode escapes will be mapped to the appropriate UTF-8 strings. If you want the JSON to not contain these escapes, give the `JSON_UNESCAPED_UNICODE` option to `json_encode` (only php 5.4+). Note that the Unicode escaping allows your JSON to traverse through 8bit-opaque channels (i.e. programs that don't correctly deal with encoding). You lose this when you specify `JSON_UNESCAPED_UNICODE`. – phihag Nov 15 '11 at 21:26
  • Thank you phihag! you're a life saver :) – eric.itzhak Nov 15 '11 at 21:35
2

Best and quickest solution I found was in the PHP Reference itself, by Sam Barnum

$encodedArray = array_map(utf8_encode, $rawArray);
marquito
  • 885
  • 11
  • 29
2
$dbh = new PDO('mysql:host=localhost;dbname=test', 
                $user, 
                $pass
              ); 

$dbh->exec("SET CHARACTER SET utf8");

or

$dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", 
                $dbuser, 
                $dbpass, 
                array( PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")
              );
kasper Taeymans
  • 6,483
  • 5
  • 29
  • 50
ouzza
  • 41
  • 3
0
function change_null($d) 
{
    if (is_array($d)) {
        foreach ($d as $k => $v) {
            $d[$k] = change_null($v);
        }
    } else if(is_null($d))
    {
        return '';
    }
    return $d;
}

This recursive function will change null values to '' empty string. When calling json_encode($your_array) to json_encode(change_null($your_array));

Metin Erbek
  • 59
  • 1
  • 7
0

One of the easiest way is to SET the CHARSET for MySQL query. If you want to set the same charset for all your queries, then just add the following in your configuration or database connection file.

mysql_query('SET CHARACTER SET utf8');

If you just want it on specific queries, then just use this right before executing your queries

0

Try json_encode($string, JSON_UNESCAPED_UNICODE); (only for PHP v5.4.0+ - see docs).

Crontab
  • 8,996
  • 1
  • 25
  • 31
  • If you use this method you will need to add the header in. [How to keep json_encode() from dropping strings with invalid characters](http://stackoverflow.com/questions/4663743/how-to-keep-json-encode-from-dropping-strings-with-invalid-characters) `header('Content-Type: application/json; charset=utf-8');` – Wingman1487 Apr 27 '15 at 00:17