【问题标题】:How does PHP use the JsonSerializable interface?PHP如何使用JsonSerializable接口?
【发布时间】:2025-12-20 11:20:09
【问题描述】:

我对@9​​87654321@ 的工作方式感到困惑。让我再详细说明一下这个问题。

通常我们使用这样的接口:

<?php
interface Countable {
    /* Methods */
    public function count();    
}

class MyThings implements Countable 
{
    public function count() {
        return count($this->arrayOfThings);
    }
}


$obj = new MyThings();

//call count method on $obj
$obj->count();

所以我们有一个类,它实现了接口。当我们调用count()函数时,它已经写在MyThings类中了。这很容易理解。

但是当我们像这样使用JsonSerializable接口时:

<?php
class Thing implements JsonSerializable {
    public function jsonSerialize() {
        // do something 
    }
}
$obj = new Thing();

//call count method on $obj
json_encode($obj);

jsonSerialize() 内部 Thingjson_encode() 调用一起运行。 如果我们打电话是可以理解的

$obj->jsonSerialize();

然后在类中有一个名为jsonSerialize() 的函数。但是,当我们运行json_encode() 时,它是如何工作的?这是如何在php中构建的?有人能解释一下这里使用的是什么类型的模式吗?

【问题讨论】:

    标签: php


    【解决方案1】:

    implement JsonSerializable 然后实现 jsonSerialize() 方法的对象。然后,当json_encode()将其输入序列化为JSON时,如果它正在序列化的值为JsonSerializable,则调用jsonSerialize()方法,该方法的result用作对象的序列化表示。

    例如,来自 PHP 文档:

    <?php
    class IntegerValue implements JsonSerializable {
        public function __construct($number) {
            $this->number = (integer) $number;
        }
    
        public function jsonSerialize() {
            return $this->number;
        }
    }
    
    echo json_encode(new IntegerValue(1), JSON_PRETTY_PRINT);
    

    会输出

    1
    

    这是代表数字 1 的 json_encoded 值。PHP 文档提供了另外三个这样的示例,从对象返回值,但是由于 jsonSerialize() 允许您指定要返回的实际数据,所以它是重要的是要意识到它可以返回任何东西。例如:

    class JsonSerializeExample implements JsonSerializable {
        public function jsonSerialize() {
            return [
                'boolean' => true,
                'random_integer' => rand(),
                'int_from_object' => new IntegerValue(42),
                'another_object' => new stdClass,
            ];
        }
    }
    $obj = new JsonSerializeExample();
    echo json_encode($obj, JSON_PRETTY_PRINT);
    

    会输出

    {
        "boolean": true,
        "random_integer": 1140562437,
        "int_from_object": 42,
        "another_object": {}
    }
    

    值得注意的是random_integer 不是存储在任何地方的静态值;它在每次执行时发生变化;而int_from_object 表明json_encode() 将递归地评估JsonSerializable 实例。

    【讨论】:

    • 但是jsonSerialize 方法是如何运行的呢?后台发生了什么魔法?
    • @SeventhSteel 这并不是真正的魔法。 json_encode() 的内部实现被编写为在尝试序列化 implements JsonSerializable 的对象时调用 jsonSerialize(),而不是采取通常用于序列化对象的操作。