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.

Answer from Matthieu Riegler on Stack Overflow
🌐
Medium
medium.com › @onwuka_gideon › how-i-fixed-php-json-encode-returning-empty-result-e4ef97638ea1
How I fixed PHP json_encode() returning empty result | by Onwuka Gideon | Medium
May 31, 2019 - If you are building a RESTful API in PHP, then you are most likely using the json_encode function. json_encode is a PHP function that converts an array to JSON format. In this article, I will discuss how you can fix a `json_encode` function that returns an empty result or throws an error.
Discussions

Any ideas about why json_encode would return empty for a request on local dev, but not empty on server?
json_encode() can fail silently for a number of reasons. I suggest adding the JSON\_THROW\_ON\_ERROR\ flag or adding something like `Log::info(json_last_error_msg())` to your code to see what's happening when you're getting no data. For me, json_encode issues have always been about a unicode character in the string, but other issues are possible. More on reddit.com
🌐 r/laravel
6
3
October 16, 2021
json_encode shows empty objects
There was an error while loading. Please reload this page · Hi, i need to pass a Query result as JSON, but my return is that: More on github.com
🌐 github.com
5
May 30, 2017
Best way to create an empty object in JSON with PHP? - Stack Overflow
If you need this to be 100% compatible ... all the objects, which is a fairly easy task). Gotchas. Only one I've found so far: is_array(new ArrayObject()) evaluates to false. You need to find and replace is_array occurrences with is_iterable. ... Well, json_encode() simply returns a string from a PHP ... More on stackoverflow.com
🌐 stackoverflow.com
php - Why json_encode returns empty brackets? - Stack Overflow
var_dump of $array returns this : array (size=3) 0 => object(frontend\models\Notifications)[101] private '_attributes' (yii\db\BaseActiveRecord) => array (size=5) ... More on stackoverflow.com
🌐 stackoverflow.com
April 26, 2017
🌐
Shounak Gupte
shounakgupte.com › json_encode-returns-an-empty-string
How to fix PHP json_encode which returns an empty string
April 13, 2015 - If you are trying to grab some information through a web service in JSON format and if PHP function json_encode returns you an empty string, you need to convert the JSON object to UTF8.
🌐
Reddit
reddit.com › r/laravel › any ideas about why json_encode would return empty for a request on local dev, but not empty on server?
r/laravel on Reddit: Any ideas about why json_encode would return empty for a request on local dev, but not empty on server?
October 16, 2021 -

I have a function written like this in my Laravel controller:

    /**
     * @param Request $request
     *
     * @throws \Illuminate\Auth\Access\AuthorizationException
     * @throws \Throwable
     */
    public function saveFreshBatch(Request $request)
    {
        Log::info("Received a new fresh batch... " . json_encode($request));
    ...

On my local, I get the following in my logs: "Received a new fresh batch... ", so a string followed by an empty array, with no text afterward, which means the result of json_encode($request) was blank. However, the object is full of data. I ran the debugger and it returned this:

> json_encode($request)
< {"attributes":{},"request":{},"query":{},"server":{},"files":{},"cookies":{},"headers":{}}

However, json_encode($request->all()) returns the correct string as if doing the whole thing, even on local.

On the production (Dev) server, I get a full JSON output, so a gigantic PHP array. In both cases I notice $request->all() gives full code.

Any ideas why the same code would result in different output, for the same object? The only thing I can think of is the headers are different, or the subclassed request is different.

Why does json_encode($request) return different outputs for the same HTTP request?

🌐
PHP
php.net › manual › en › function.json-encode.php
PHP: json_encode - Manual
Like the reference JSON encoder, json_encode() will generate JSON that is a simple value (that is, neither an object nor an array) if given a string, int, float or bool as an input value. While most decoders will accept these values as valid JSON, some may not, as the specification is ambiguous on this point. To summarise, always test that your JSON decoder can handle the output you generate from json_encode(). ... json_last_error_msg() - Returns the error string of the last json_validate(), json_encode() or json_decode() call
🌐
GitHub
github.com › parse-community › parse-php-sdk › issues › 319
json_encode shows empty objects · Issue #319 · parse-community/parse-php-sdk
May 30, 2017 - parse-community / parse-php-sdk Public · There was an error while loading. Please reload this page. Notifications · You must be signed in to change notification settings · Fork 341 · Star 808 · New issueCopy link · New issueCopy link · Closed · Closed · json_encode shows empty objects#319 · Copy link · mauriciord · opened · on May 30, 2017 · Issue body actions · Hi, i need to pass a Query result as JSON, but my return is that: [{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}] My code: $lotQuery = new ParseQuery("Loteamento"); $lotQuery->notEqu
Author: parse-community
Top answer
1 of 4
160

Recommended method

json_decode ("{}") will return a stdClass per default, using the below should therefor be considered safe/portable and correct.

json_encode (new stdClass);


Your solution could work..

The documentation specifies that (object) null will result in an empty object, some might therefor say that your code is valid and that it's the method to use.

PHP: Objects - Manual

If a value of any other type is converted to an object, a new instance of the stdClass built-in class is created. If the value was NULL, the new instance will be empty.

.. but, try to keep it safe!

Though you never know when/if the above will change, so if you'd like to be 100% certain that you will always will end up with a {} in your encoded data you could use a hack such as:

$empty = json_decode ("{}");
$result = json_encode($empty); // "{}"

Even though it's tedious and ugly I do assume/hope that json_encode/json_decode is compatible with one another and always will evaluate the following to true:

$a = <something>;

$a === json_decode (json_encode ($a)); 
2 of 4
112

If you use objects as dynamic dictionaries (and I guess you do), then I think you want to use an ArrayObject.

It maps into JSON dictionary even when it's empty. It is great if you need to distinguish between lists (arrays) and dictionaries (associative arrays):

$complex = array('list' => array(), 'dict' => new ArrayObject());
print json_encode($complex); // -> {"list":[],"dict":{}}

You can also manipulate it seamlessly (as you would do with an associative array), and it will keep rendering properly into a dictionary:

$complex['dict']['a'] = 123;
print json_encode($complex); // -> {"list":[],"dict":{"a":123}}

unset($complex['dict']['a']);
print json_encode($complex); // -> {"list":[],"dict":{}}

If you need this to be 100% compatible both ways, you can also wrap json_decode so that it returns ArrayObjects instead of stdClass objects (you'll need to walk the result tree and recursively replace all the objects, which is a fairly easy task).

Gotchas. Only one I've found so far: is_array(new ArrayObject()) evaluates to false. You need to find and replace is_array occurrences with is_iterable.

🌐
Blogger
anvnguyen.blogspot.com › 2015 › 07 › php-jsonencode-return-empty-array.html
PHP json_encode return empty array [] instead of empty object {}
July 27, 2015 - If so, follow this simple solution: Developer just uses normal array() function and then use flag JSON_FORCE_OBJECT when encode the array: ... JSON_FORCE_OBJECT (integer) Outputs an object rather than an array when a non-associative array is used. Especially useful when the recipient of the output is expecting an object and the array is empty. Available since PHP 5.3.0.
Find elsewhere
🌐
Elastic
elastic.co › docs › reference › elasticsearch › clients › php › configuration › dealing with json arrays and objects in php
Dealing with JSON arrays and objects in PHP | PHP
By using an explicit stdClass object, we can force the json_encode parser to correctly output an empty object, instead of an empty array. This verbose solution is the only way to acomplish the goal in PHP…
🌐
Codementor
codementor.io › community › how to debug/fix php json_encode() that returns an empty result
How to Debug/Fix PHP json_encode() that returns an empty result | Codementor
January 17, 2020 - Add the below code in your code after the json_encode() function that you have: ... echo json_last_error_msg(); // Print out the error if any die(); // halt the script · Run the script again. If what was printed out is — “No errors”, then there is nothing wrong with the data. ... https://secure.php.net/manual/en/function.json-last-error.php#refsect1-function.json-last-error-examples
Top answer
1 of 1
1

You really should include the actual JSON in your question; without it we are working blind, but I can guess what the problem is. You are not constructing your JSON properly when there are multiple records. When you have a single recipient, your JSON might look like this:

{"readyState":4,"responseText":"","status":200,"statusText":"OK"}

That is fine, and perfectly valid JSON – and there is no issue having an empty string as a value. The problem arises when you have more than one record, when it will append them immediately after the first:

{"readyState":4,"responseText":"","status":200,"statusText":"OK"}{"readyState":4,"responseText":"","status":200,"statusText":"OK"}

This is not valid JSON.

I suggest you accumulate your JSON responses inside the loop and then output them afterwards, in the correct format. Something like:

$jsonData = [];
foreach ($emails_room_f as $email_room_f){
    //set your content in $data as you are now, then:
    $jsonData[] = $data;
}
header("Content-Type: application/json; charset=utf-8", true);
echo json_encode($jsonData);

This way you will end up with data like this:

[
    {"readyState":4,"responseText":"","status":200,"statusText":"OK"},
    {"readyState":4,"responseText":"","status":200,"statusText":"OK"}
]

Which is valid JSON. It will also work if there is no data as it will return an empty array, which is also valid JSON.

Separately from this, I am extremely suspicious of you having a utf8ize function – that is a sign you're doing other UTF-8 stuff wrong, but that's a subject for another question.

Top answer
1 of 2
4

It is because your class's properties are private.

An example class with only private properties ...

php > class Foo { private $bar = 42; }
php > $obj = new Foo();

do not expose values:

php > echo json_encode($obj);
{}

But an example class with public properties ...

php > class Bar { public $foo = 42; }
php > $objBar = new Bar();

do it!

php > echo json_encode($objBar);
{"foo":42}

\JsonSerializable

PHP provide an'interafce \JsonSerializable that require a method jsonSerialize. This method is automatically called by json_encode().

class JsonClass implements JsonSerialize {
    private $bar;
    public function __construct($bar) {
        $this->bar = $bar;
    }
    public function jsonSerialize() {
        return [
            'foo' => $this->bar,
        ];
    }
}

I prefer this solution because is not good to expose publicly properties

serialization and unserialization ...

If you need to serialize and unserialize php object you can ...

php > class Classe { public $pub = "bar"; }
php > $obj = new Classe();
php > $serialized = serialize($obj);
php > $original = unserialize($serialized);
php > var_dump($original);
php shell code:1:
class Classe#2 (1) {
  public $pub =>
  string(3) "bar"
}

$serialized variable contains O:6:"Classe":1:{s:3:"pub";s:3:"bar";}. As you can see is not a json, but is a format that allow you to recreate original object using unserialize function.

2 of 2
0

You have a couple of options here.

Option 1: Make your class properties public

Like what sensorario mentioned, change the visibility of your properties so that it is accessible from outside the class, which is where you are calling json_encode.

Option 2: Introduce a method/function within the class to return the encoded JSON object

Have a toJson() function inside your User class.

Of course, there are way more options - such as extending User so that User is not "contaminated", etc.

But yup, the general problem is your private properties.

🌐
Drupal
drupal.org › project › search_api_solr › issues › 2970829
PHP 7.x json_decode() no longer gives '_empty_' for empty keys [#2970829] | Drupal.org
June 5, 2018 - But I suppose this would be too much of a BC break and too big a change now. ... See the changelog! 7.1.0 An empty JSON key ("") can be encoded to the empty object property instead of using a key with value _empty_. ... /** * @var string $emptykey * Either '' or '_empty_', depending on PHP version.
🌐
w3tutorials
w3tutorials.net › blog › why-would-json-encode-return-an-empty-string
Why Does json_encode Return an Empty String in PHP? Troubleshooting Nested Arrays — w3tutorials.net
json_encode() returning an "empty string" is almost always a sign it failed (returned false), often due to issues in nested arrays. By checking for errors with json_last_error(), validating UTF-8 encoding, inspecting data types, and handling ...
🌐
Codementor
codementor.io › community › how i fixed php json_encode() returning empty result
How I fixed PHP json_encode() returning empty result | Codementor
November 15, 2022 - Add the below code in your code after the json_encode() function that you have: echo json_last_error_msg(); // Print out the error if any die(); // halt the script · If what was printed out is — “No errors”, then there is nothing wrong with the data. ... https://secure.php.net/manual/en/function.json-last-error.php#refsect1-function.json-last-error-examples
🌐
GitHub
gist.github.com › tureki › 7af3ea2554eba60c34c5
json_encode null to empty string. · GitHub
json_encode null to empty string. GitHub Gist: instantly share code, notes, and snippets.