PHP Conference Japan 2024

JsonSerializable::jsonSerialize

(PHP 5 >= 5.4.0, PHP 7, PHP 8)

JsonSerializable::jsonSerialize指定要序列化為 JSON 的資料

說明

public JsonSerializable::jsonSerialize(): mixed

將物件序列化為可由 json_encode() 原生序列化的值。

參數

此函式沒有參數。

回傳值

返回可被 json_encode() 序列化的資料,其值可以是除了 資源 以外的任何類型。

範例

範例 #1 JsonSerializable::jsonSerialize() 範例,返回一個 陣列

<?php
class ArrayValue implements JsonSerializable {
private
$array;
public function
__construct(array $array) {
$this->array = $array;
}

public function
jsonSerialize(): mixed {
return
$this->array;
}
}

$array = [1, 2, 3];
echo
json_encode(new ArrayValue($array), JSON_PRETTY_PRINT);
?>

上述範例會輸出

[
    1,
    2,
    3
]

範例 #2 JsonSerializable::jsonSerialize() 範例,返回一個關聯式 陣列

<?php
class ArrayValue implements JsonSerializable {
private
$array;
public function
__construct(array $array) {
$this->array = $array;
}

public function
jsonSerialize() {
return
$this->array;
}
}

$array = ['foo' => 'bar', 'quux' => 'baz'];
echo
json_encode(new ArrayValue($array), JSON_PRETTY_PRINT);
?>

上述範例會輸出

{
    "foo": "bar",
    "quux": "baz"
}

範例 #3 JsonSerializable::jsonSerialize() 範例,返回一個 整數

<?php
class IntegerValue implements JsonSerializable {
private
$number;
public function
__construct($number) {
$this->number = (int) $number;
}

public function
jsonSerialize() {
return
$this->number;
}
}

echo
json_encode(new IntegerValue(1), JSON_PRETTY_PRINT);
?>

上述範例會輸出

1

範例 #4 JsonSerializable::jsonSerialize() 範例,回傳一個 字串

<?php
class StringValue implements JsonSerializable {
private
$string;
public function
__construct($string) {
$this->string = (string) $string;
}

public function
jsonSerialize() {
return
$this->string;
}
}

echo
json_encode(new StringValue('Hello!'), JSON_PRETTY_PRINT);
?>

上述範例會輸出

"Hello!"

新增註解

使用者貢獻的註解 4 則註解

benkuhl at gmail dot com
11 年前
使用此功能的一個很好的例子是在處理物件時。

json_encode() 會將 DateTime 轉換為

{
"date":"2013-01-31 11:14:05",
"timezone_type":3,
"timezone":"America\/Los_Angeles"
}

這在使用 PHP 時很棒,但如果日期是由 Java 讀取的。 Java 日期解析器不知道如何處理它。 但它知道如何處理 ISO8601 格式...

<?php

date_default_timezone_set
('America/Los_Angeles');

class
Fruit implements JsonSerializable {
public
$type = 'Apple',
$lastEaten = null;

public function
__construct() {
$this->lastEaten = new DateTime();
}

public function
jsonSerialize() {
return [
'type' => $this->type,
'lastEaten' => $this->lastEaten->format(DateTime::ISO8601)
];
}
}
echo
json_encode(new Fruit()); // 輸出結果:{"type":"Apple","lastEaten":"2013-01-31T11:17:07-0500"}

?>
tomasz dot darmetko at gmail dot com
7 年前
巢狀的 JSON 可序列化物件將會被遞迴序列化。不需要自行呼叫 ->jsonSerialize() 方法。這在集合中特別有用。

<?php

class NestedSerializable implements \JsonSerializable
{

private
$serializable;

public function
__construct($serializable)
{
$this->serializable = $serializable;
}

public function
jsonSerialize()
{
return [
'serialized' => $this->serializable
];
}

}

class
SerializableCollection implements \JsonSerializable {

private
$elements;

public function
__construct(array $elements)
{
$this->elements = $elements;
}

public function
jsonSerialize()
{
return
$this->elements;
}

}

// 輸出結果:[{"serialized":null},{"serialized":null},{"serialized":{"serialized":null}}]
echo json_encode(
new
SerializableCollection([
new
NestedSerializable(null),
new
NestedSerializable(null),
new
NestedSerializable(new NestedSerializable(null))
])
);

?>
info at digistratum dot com
7 年前
這裡有一個小測試/證明,可以很容易地看到一些比較結果。我對 Null 感興趣,因為它沒有被記錄在文件中。

<?php
類別 jsontest 實作 JsonSerializable {
函式
__construct($value) { $this->value = $value; }
函式
jsonSerialize() { return $this->value; }
}

print
"空值 -> " . json_encode(new jsontest(null)) . "\n";
print
"陣列 -> " . json_encode(new jsontest(array(1,2,3))) . "\n";
print
"關聯式陣列 -> " . json_encode(new jsontest(array('a'=>1,'b'=>3,'c'=>4))) . "\n";
print
"整數 -> " . json_encode(new jsontest(5)) . "\n";
print
"字串 -> " . json_encode(new jsontest('Hello, World!')) . "\n";
print
"物件 -> " . json_encode(new jsontest((object) array('a'=>1,'b'=>3,'c'=>4))) . "\n";
?>

輸出結果為
空值 -> null
陣列 -> [1,2,3]
關聯式陣列 -> {"a":1,"b":3,"c":4}
整數 -> 5
字串 -> "Hello, World!"
物件 -> {"a":1,"b":3,"c":4}
david at vanlaatum dot id dot au
9 年前
simonsimcity at gmail dot com 的說法是錯誤的,你可以在這裡拋出例外,但它會被另一個例外包裝,所以他的範例會輸出

PHP 致命錯誤:未捕捉到的例外 'RuntimeException',訊息為 'It failed!',位於 -:8
堆疊追蹤
#0 [內部函式]: Foo->jsonSerialize()
#1 -(16): json_encode(Object(Foo))
#2 {main}

下一個例外 'Exception',訊息為 'Failed calling Foo::jsonSerialize()',位於 -:16
堆疊追蹤
#0 -(0): json_encode()
#1 {main}
拋出於 - 的第 16 行

PHP 5.4.39
To Top