yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.24k stars 6.91k forks source link

Wrong behavior of Json helper. #17913

Closed misq007 closed 4 years ago

misq007 commented 4 years ago

What steps will reproduce the problem?

<?php
$data = [
    0 => 'test'
];
$data = (object)$data;

echo \yii\helpers\Json::encode($data); // ["test"]
// echo json_encode($data); // {"0":"test"}
exit;

I have a custom API that is using Yii::$app->response->format = \yii\web\Response::FORMAT_JSON and returns a list with groups where the group_id was a key. Note that in my case the 0 was the ID of a group and only one group was returned.

What is the expected result?

{"0":"test"}

What do you get instead?

["test"]

json_encode($data); works fine. The problem occurs because you foreach it and convert it to array here: https://github.com/yiisoft/yii2/blob/master/framework/helpers/BaseJson.php#L171

I think it should check if:

($data instanceof stdClass) {
    return $data;
}

Additional info

Q A
Yii version 2.0.32
PHP version 5.6
Operating system centos
kamarton commented 4 years ago

For incremental numeric keys (0, 1, 2 ...) in PHP is interpreted as a JSON array.

Incremental, started from zero, string type keys:

$ php -r 'var_dump(json_encode(["0" => "a","1" => "b"]));'
string(9) "["a","b"]"

not incremental:

$ php -r 'var_dump(json_encode([1 => "a",0 => "b"]));'
string(17) "{"1":"a","0":"b"}"
$ php -r 'var_dump(json_encode(["0" => "a","2" => "b"]));'
string(17) "{"0":"a","2":"b"}"
misq007 commented 4 years ago

Please see that I cast it to object in purpose: $data = (object)$data; and note that json_encode works fine.

In my case, it was a filter that returns only a special group with ID 0. But without filter - it returns 0 and 13 which is fine.

The Yii Json helper should not break the behavior of json_encode because people do not expect it and it causing hard to find bugs.

I think this should be fixed.


Please read and test my example and the proposed solution.

rob006 commented 4 years ago

Duplicate of https://github.com/yiisoft/yii2/issues/16621