假设我们有一个简单的对象来使用嵌套对象进行序列化:
class User implements \JsonSerializable
{
private $name;
private $email;
private $address;
public function jsonSerialize()
{
return [
'name' => $this->name,
'email' => $this->email,
'address' => $this->address
];
}
}
嵌套对象:
class Address implements \JsonSerializable
{
private $city;
private $state;
public function jsonSerialize()
{
return [
'city' => $this->city,
'state' => $this->state
];
}
}
我们使用json_encode()
进行序列化,这将使用原生JsonSerializable::jsonSerialize():
$json = json_encode($user);
如果$name
和$state
为空,请告知如何:
{
"email": "john.doe@test.com",
{
"city": "Paris"
}
}
而不是:
{
"name": null,
"email": "john.doe@test.com",
{
"city": "Paris",
"state": null
}
}
答案 0 :(得分:1)
在返回的数组周围包裹array_filter
,例如
public function jsonSerialize()
return array_filter([
'city' => $this->city,
'state' => $this->state
]);
}
这将删除任何等于false(松散比较)的条目,其中包括任何空值,但也包括0和false。如果您需要严格,例如只有空值,提供以下回调:
function($val) { return !is_null($val); }
请参阅array_filter
的文档:
(PHP 4> = 4.0.6,PHP 5,PHP 7)
迭代数组中的每个值,将它们传递给回调函数。如果回调函数返回true,则将数组中的当前值返回到结果数组中。数组键被保留。
另一个选择是使用JMX Serializer,这是一个高度可配置的JSON,XML和YAML序列化程序。但它要重得多。有关详细信息,请参阅Exclude null properties in JMS Serializer。
答案 1 :(得分:0)
我的评论不正确,array_walk_recursive()
可以更改值,但不能取消设置,所以我创建了一个自定义递归函数,只需几行代码:
<?php
$a = (object) array(
'first' => null,
'second' => 10,
'third' => (object) array(
'second-first' => 100,
'second-second' => null,
'second-third' => 300
),
'fourth' => 20,
'fifth' => null,
'sixth' => 10);
function remove_null_values($a) {
$ret = (is_array($a) ? array() : new stdClass());
foreach ($a as $k => $v) {
if (is_array($v) || is_object($v)) {
if (is_object($ret))
$ret->$k = remove_null_values($v);
else
$ret[$k] = remove_null_values($v);
}
elseif (!is_null($v)) {
if (is_object($ret))
$ret->$k = $v;
else
$ret[$k] = $v;
}
}
return $ret;
}
输出:
object(stdClass)#2 (6) {
["first"]=>
NULL
["second"]=>
int(10)
["third"]=>
object(stdClass)#1 (3) {
["second-first"]=>
int(100)
["second-second"]=>
NULL
["second-third"]=>
int(300)
}
["fourth"]=>
int(20)
["fifth"]=>
NULL
["sixth"]=>
int(10)
}
object(stdClass)#3 (4) {
["second"]=>
int(10)
["third"]=>
object(stdClass)#4 (2) {
["second-first"]=>
int(100)
["second-third"]=>
int(300)
}
["fourth"]=>
int(20)
["sixth"]=>
int(10)
}
编辑:我更新了代码以同时使用嵌套数组和对象,如果你不需要数组部分功能,那么将它排除在外是很容易的,我会让你处理细节