JsonSerializable::jsonSerialize
(PHP 5 >= 5.4.0)
JsonSerializable::jsonSerialize — Задает данные, которые должны быть сериализованы в JSON
Описание
Сериализует объект в значение, которое в свою очередь может быть сериализовано функицей json_encode().
Список параметров
У этой функции нет параметров.
Возвращаемые значения
Возвращает данные, которые могут быть сериализованы json_encode(), которые являются значением любого типа, отличным от типа resource.
Примеры
Пример #1 Пример использования JsonSerializable::jsonSerialize(), возвращающий массив (array)
<?php
class ArrayValue implements JsonSerializable {
public function __construct(array $array) {
$this->array = $array;
}
public function jsonSerialize() {
return $this->array;
}
}
$array = [1, 2, 3];
echo json_encode(new ArrayValue($array), JSON_PRETTY_PRINT);
?>
Результат выполнения данного примера:
[ 1, 2, 3 ]
Пример #2 Пример использования JsonSerializable::jsonSerialize(), возвращающий ассоциативный массив (array)
<?php
class ArrayValue implements JsonSerializable {
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(), возвращающий целое значение (integer)
<?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
Пример #4 Пример использования JsonSerializable::jsonSerialize(), возвращающий строку (string)
<?php
class StringValue implements JsonSerializable {
public function __construct($string) {
$this->string = (string) $string;
}
public function jsonSerialize() {
return $this->string;
}
}
echo json_encode(new StringValue('Hello!'), JSON_PRETTY_PRINT);
?>
Результат выполнения данного примера:
"Hello!"
Коментарии
A good example on when you would use functionality like this is when working with objects.
json_encode() will take a DateTime and convert it to:
{
"date":"2013-01-31 11:14:05",
"timezone_type":3,
"timezone":"America\/Los_Angeles"
}
This is great when working with PHP, but if the Date is being read by Java. The Java date parser doesn't know what to do with that. But it does know what to do with the ISO8601 format...
<?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()); //which outputs: {"type":"Apple","lastEaten":"2013-01-31T11:17:07-0500"}
?>
simonsimcity at gmail dot com is wrong, you can throw exceptions in this but it will wrap with another exception so his example outputs
PHP Fatal error: Uncaught exception 'RuntimeException' with message 'It failed!' in -:8
Stack trace:
#0 [internal function]: Foo->jsonSerialize()
#1 -(16): json_encode(Object(Foo))
#2 {main}
Next exception 'Exception' with message 'Failed calling Foo::jsonSerialize()' in -:16
Stack trace:
#0 -(0): json_encode()
#1 {main}
thrown in - on line 16
PHP 5.4.39
Here's a small test/proof that makes it easy to see some comparative results. Null was the one I was interested in since it was not documented:
<?php
class jsontest implements JsonSerializable {
function __construct($value) { $this->value = $value; }
function jsonSerialize() { return $this->value; }
}
print "Null -> " . json_encode(new jsontest(null)) . "\n";
print "Array -> " . json_encode(new jsontest(Array(1,2,3))) . "\n";
print "Assoc. -> " . json_encode(new jsontest(Array('a'=>1,'b'=>3,'c'=>4))) . "\n";
print "Int -> " . json_encode(new jsontest(5)) . "\n";
print "String -> " . json_encode(new jsontest('Hello, World!')) . "\n";
print "Object -> " . json_encode(new jsontest((object) Array('a'=>1,'b'=>3,'c'=>4))) . "\n";
?>
Output is:
Null -> null
Array -> [1,2,3]
Assoc. -> {"a":1,"b":3,"c":4}
Int -> 5
String -> "Hello, World!"
Object -> {"a":1,"b":3,"c":4}
Nested json serializable objects will be serialized recursively. No need to call ->jsonSerialize() on your own. It is especially useful in collections.
<?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;
}
}
// Outputs: [{"serialized":null},{"serialized":null},{"serialized":{"serialized":null}}]
echo json_encode(
new SerializableCollection([
new NestedSerializable(null),
new NestedSerializable(null),
new NestedSerializable(new NestedSerializable(null))
])
);
?>
For those who are also lazy. You cannot just include $this and expect it to work.
For example, this won't work:
<?php
class SomeClass implements JsonSerializable {
protected $partner;
function setPartner(object $partner) {
$this->partner;
}
public function jsonSerialize() {
return $this;
}
}
$foo = new SomeClass();
$too = new stdClass();
$too->test = 1;
$foo->setPartner = $too;
echo json_encode($foo); // Shows a blank object "{}"
?>
You have to define the things manually, so this will work.
<?php
class SomeClass implements JsonSerializable {
protected $partner;
function setPartner(object $partner) {
$this->partner;
}
public function jsonSerialize() {
$data['partner'] = $this->partner;
return $data;
}
}
$foo = new SomeClass();
$too = new stdClass();
$too->test = 1;
$foo->setPartner = $too;
echo json_encode($foo); // Shows {"partner":{"test":1}}