将PHP对象序列化为JSON

因此,当我偶然发现新的JsonSerializable

Interface时,我在php.net上四处徘徊,以获取有关将PHP对象序列化为JSON的信息。它只是

,而我正在5.3.x环境中运行。


如何实现这种功能?

我还没有使用JSON进行很多工作,但是我试图在应用程序中支持API层,并且将数据对象( 否则将发送到视图 )转储到JSON中将是完美的。

如果我尝试直接序列化该对象,它将返回一个空的JSON字符串;这是因为我假设json_encode()不知道该对象要做什么。应我递归降低对象到一个数组,然后编码


$data = new Mf_Data();

$data->foo->bar['hello'] = 'world';

产生一个空对象:

{}

但是,按预期方式工作:

object(Mf_Data)#1 (5) {

["_values":"Mf_Data":private]=>

array(0) {

}

["_children":"Mf_Data":private]=>

array(1) {

[0]=>

array(1) {

["foo"]=>

object(Mf_Data)#2 (5) {

["_values":"Mf_Data":private]=>

array(0) {

}

["_children":"Mf_Data":private]=>

array(1) {

[0]=>

array(1) {

["bar"]=>

object(Mf_Data)#3 (5) {

["_values":"Mf_Data":private]=>

array(1) {

[0]=>

array(1) {

["hello"]=>

string(5) "world"

}

}

["_children":"Mf_Data":private]=>

array(0) {

}

["_parent":"Mf_Data":private]=>

*RECURSION*

["_key":"Mf_Data":private]=>

string(3) "bar"

["_index":"Mf_Data":private]=>

int(0)

}

}

}

["_parent":"Mf_Data":private]=>

*RECURSION*

["_key":"Mf_Data":private]=>

string(3) "foo"

["_index":"Mf_Data":private]=>

int(0)

}

}

}

["_parent":"Mf_Data":private]=>

NULL

["_key":"Mf_Data":private]=>

NULL

["_index":"Mf_Data":private]=>

int(0)

}


附录

回答:

所以这是toArray()我为Mf_Data课程设计的功能:

public function toArray()

{

$array = (array) $this;

array_walk_recursive($array, function (&$property) {

if ($property instanceof Mf_Data) {

$property = $property->toArray();

}

});

return $array;

}

但是,由于Mf_Data对象也具有对其父对象( 包含 )的引用,因此递归操作将失败。尽管当我删除_parent引用时,它的工作原理像一个咒语。

回答:

为了跟进,转换我所使用的复杂树节点对象的最后一个函数是:

// class name - Mf_Data

// exlcuded properties - $_parent, $_index

public function toArray()

{

$array = get_object_vars($this);

unset($array['_parent'], $array['_index']);

array_walk_recursive($array, function (&$property) {

if (is_object($property) && method_exists($property, 'toArray')) {

$property = $property->toArray();

}

});

return $array;

}

回答:

我再次跟进,对实现进行了一些清洁。使用接口为instanceof检查似乎更清洁比method_exists()

method_exists()不横切继承/实现)。

使用unset()似乎也有些混乱,并且似乎应该将逻辑重构为另一种方法。但是,此实现 确实 复制了属性数组(

归因于array_diff_key),因此需要考虑一些事情。

interface ToMapInterface

{

function toMap();

function getToMapProperties();

}

class Node implements ToMapInterface

{

private $index;

private $parent;

private $values = array();

public function toMap()

{

$array = $this->getToMapProperties();

array_walk_recursive($array, function (&$value) {

if ($value instanceof ToMapInterface) {

$value = $value->toMap();

}

});

return $array;

}

public function getToMapProperties()

{

return array_diff_key(get_object_vars($this), array_flip(array(

'index', 'parent'

)));

}

}

回答:


:目前是2016年9月24日,PHP 5.4已于2012-03-01发布,支持 已于 2015-09-01 结束

。不过,这个答案似乎获得了好评。如果您仍在使用PHP <5.4, 则可能会带来安全隐患,并破坏您的项目

。如果您没有令人信服的理由停留在<5.4,或者甚至已经使用版本> = 5.4, ,而只需使用PHP> =

5.4(或者您知道是最近的版本)并实现JsonSerializable接口


您将定义一个函数(例如named)getJsonData();,该函数将返回数组,stdClass对象或其他具有可见参数的对象,而不是私有/受保护的参数,然后执行json_encode($data->getJsonData());。本质上,从5.4开始实现该功能,但要手动调用它。

可以get_object_vars()从类内部调用这样的方法,它可以访问私有/受保护的变量:

function getJsonData(){

$var = get_object_vars($this);

foreach ($var as &$value) {

if (is_object($value) && method_exists($value,'getJsonData')) {

$value = $value->getJsonData();

}

}

return $var;

}

以上是 将PHP对象序列化为JSON 的全部内容, 来源链接: utcz.com/qa/415809.html

回到顶部