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.9k forks source link

yii\rest\Serializer not works as expected #20078

Closed codeclass closed 11 months ago

codeclass commented 11 months ago

What steps will reproduce the problem?

example model

class SomeClass extends \yii\db\ActiveRecord implements \JsonSerializable {
  ...

    function jsonSerialize()
    {
        $addField = ['test' => '111'];
        return ArrayHelper::merge($this->getAttributes(), $addField);
    }

}

then try to Serialize with yii\rest\Serializer

$serializer = new yii\rest\Serializer();
var_dump($serializer->serialize(new SomeClass()))

What is the expected result?

expected test field in dump

What do you get instead?

no test field in dump

Additional info

Model is serializing like Arrayable

https://github.com/yiisoft/yii2/blob/d43341a73ab9ab711c42b74c117e076275d9b8c0/framework/rest/Serializer.php#L149

it is JsonSerializable too, but this code is not running:

https://github.com/yiisoft/yii2/blob/d43341a73ab9ab711c42b74c117e076275d9b8c0/framework/rest/Serializer.php#L151

Q A
Yii version 2.0.49
PHP version 7.4
Operating system Debian 12
bizley commented 11 months ago

It's because \yii\db\ActiveRecord is Arrayable. With current framework implementation you need to have your own Serializer (or at least overwritten serialize()) to change the order of these if conditions. Maybe we should introduce some customizable order? 🤔

codeclass commented 11 months ago

Im using Controller that implements yii\rest\Controller and this serializer used by afterAction method. I can make my own serializer and point it at $serializer in my extended controller, but I think it is not nice.

May be possible to check, if model is JsonSerializable in "serializeModel" function and merge additional fields? https://github.com/yiisoft/yii2/blob/d43341a73ab9ab711c42b74c117e076275d9b8c0/framework/rest/Serializer.php#L261

bizley commented 11 months ago

Wouldn't it be hard to decide which fields are to be kept and which are to be overwritten and in what order?