Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would json_encode return an empty string

Tags:

json

php

People also ask

What does the PHP function json_encode () do?

PHP | json_encode() Function The json_encode() function is an inbuilt function in PHP which is used to convert PHP array or object into JSON representation.

What is json_encode in JavaScript?

The PHP json_encode function translates the data passed to it to a JSON string which can then be output to a JavaScript variable. We demonstrate on this page with single level arrays. Other pages demonstrate using json_encode with multi-dimensional arrays and scalar values.

What is json_encode and Json_decode?

JSON data structures are very similar to PHP arrays. PHP has built-in functions to encode and decode JSON data. These functions are json_encode() and json_decode() , respectively. Both functions only works with UTF-8 encoded string data.


Well after 2 hours of digging (cf Edits)

I found out following :

  • In my case it's a encoding problem
  • mb_detect_encoding returns probably a faulty response, some strings were probably not UTF-8
  • using utf8_encode() on those string solved my problem, but see note below

Here is a recursive function that can force convert to UTF-8 all the strings contained in an array:

function utf8ize($d) {
    if (is_array($d)) {
        foreach ($d as $k => $v) {
            $d[$k] = utf8ize($v);
        }
    } else if (is_string ($d)) {
        return utf8_encode($d);
    }
    return $d;
}

Use it simply like this:

echo json_encode(utf8ize($data));

Note: utf8_encode() encodes ISO-8859-1 string to UTF-8 as per the docs so if you are unsure of the input encoding iconv() or mb_convert_encoding() may be better options as noted in comments and other solutions.


Matthieu Riegler presented really good solution however I had to slightly modify it to handle objects too:

function utf8ize($d) {
    if (is_array($d)) 
        foreach ($d as $k => $v) 
            $d[$k] = utf8ize($v);

     else if(is_object($d))
        foreach ($d as $k => $v) 
            $d->$k = utf8ize($v);

     else 
        return utf8_encode($d);

    return $d;
}

One more note: json_last_error() may be helpful in debugging json_encode()/json_encode() functions.


For me, the answer to this problem was setting charset=utf8 in my PDO connection.

$dbo = new PDO('mysql:host=localhost;dbname=yourdb;charset=utf8', $username, $password);

Adam Bubela also presented really good solution who helped me solved my problem, and here is the simplified function :

function utf8ize($d)
{ 
    if (is_array($d) || is_object($d))
        foreach ($d as &$v) $v = utf8ize($v);
    else
        return utf8_encode($d);

    return $d;
}

I have exactly the same problem on PHP 5.6. I use Open Server + Nginx on Windows 7. All charsets are set to UTF-8. In theory, according the official documentation, flag

JSON_UNESCAPED_UNICODE

should solve this. Unfortunately this is not my case. I do not know, why. All snippets above do not solve my problem, thus I have found my own implementation. I believe it could help someone. At least, Russian letters pass the test.

function utf8ize($d) {
    if (is_array($d) || is_object($d)) {
        foreach ($d as &$v) $v = utf8ize($v);
    } else {
        $enc   = mb_detect_encoding($d);

        $value = iconv($enc, 'UTF-8', $d);
        return $value;
    }

    return $d;
}

This accepted answer works. But in case you are getting your data from MySQL (as I was) there is an easier way.

Once you open you database, before you query you can set the character set using mysqli as follows:

/* change character set to utf8 | Procedural*/
if (!mysqli_set_charset($link, "utf8")) {
    printf("Error loading character set utf8: %s\n", mysqli_error($link));
    exit();
}

OR

/* change character set to utf8 | Object Oriented*/
if (!$mysqli->set_charset("utf8")) {
        printf("Error loading character set utf8: %s\n", $mysqli->error);
        exit();
 }

LINK: http://php.net/manual/en/mysqli.set-charset.php


I ran into this issue on a server running an older version of PHP (5.2). I was using the JSON_FORCE_OBJECT flag, and apparently that isn't supported until 5.3

So if you're using that flag be sure to check your version!

A workaround appears to be just casting to an object before encoding, like:

json_encode((object)$myvar);