Pet*_*ley 11 php serialization json
我遇到了一个奇怪的问题,我不知道如何解决它.我有几个类都是JSON对象的PHP实现.这是'问题的一个例子
class A
{
protected $a;
public function __construct()
{
$this->a = array( new B, new B );
}
public function __toString()
{
return json_encode( $this->a );
}
}
class B
{
protected $b = array( 'foo' => 'bar' );
public function __toString()
{
return json_encode( $this->b );
}
}
$a = new A();
echo $a;
Run Code Online (Sandbox Code Playgroud)
这个输出是
[{},{}]
Run Code Online (Sandbox Code Playgroud)
当所需的输出是
[{"foo":"bar"},{"foo":"bar"}]
Run Code Online (Sandbox Code Playgroud)
问题是我依靠__toString()钩子来为我做我的工作.但它不能,因为json_encode()使用的序列化不会调用__toString().遇到嵌套对象时,它只是序列化公共属性.
那么,问题就变成了这样:有没有办法可以开发一个JSON类的托管接口,它既可以让我使用setter和getter来获取属性,也可以让我获得我想要的JSON序列化行为?
如果这是不明确的,这里是一个实现的例子就不会工作,因为__set()钩子只要求初始分配
class a
{
public function __set( $prop, $value )
{
echo __METHOD__, PHP_EOL;
$this->$prop = $value;
}
public function __toString()
{
return json_encode( $this );
}
}
$a = new a;
$a->foo = 'bar';
$a->foo = 'baz';
echo $a;
Run Code Online (Sandbox Code Playgroud)
我想我也可以这样做
class a
{
public $foo;
public function setFoo( $value )
{
$this->foo = $value;
}
public function __toString()
{
return json_encode( $this );
}
}
$a = new a;
$a->setFoo( 'bar' );
echo $a;
Run Code Online (Sandbox Code Playgroud)
但后来我不得不依赖其他开发人员的勤奋使用setter - 我不能强制遵循这个解决方案的程序.
--->编辑<---
现在测试一下Rob Elsner的回应
<?php
class a implements IteratorAggregate
{
public $foo = 'bar';
protected $bar = 'baz';
public function getIterator()
{
echo __METHOD__;
}
}
echo json_encode( new a );
Run Code Online (Sandbox Code Playgroud)
执行此操作时,您可以看到不会调用getIterator()方法.
Tiv*_*vie 27
答案较晚,但对于遇到同样问题的其他人可能会有用.
在PHP <5.4.0 json_encode中,不会从对象调用任何方法.这对getIterator,__ serialize等有效...
但是,在PHP> v5.4.0中,引入了一个名为JsonSerializable的新接口.
它基本上控制了在该对象json_encode上调用时对象的行为.
小提琴(嗯,实际上是PHP CodePad,但同样的事情......)
示例:
class A implements JsonSerializable
{
protected $a = array();
public function __construct()
{
$this->a = array( new B, new B );
}
public function jsonSerialize()
{
return $this->a;
}
}
class B implements JsonSerializable
{
protected $b = array( 'foo' => 'bar' );
public function jsonSerialize()
{
return $this->b;
}
}
$foo = new A();
$json = json_encode($foo);
var_dump($json);
Run Code Online (Sandbox Code Playgroud)
输出:
string(29)"[{"foo":"bar"},{"foo":"bar"}]"
| 归档时间: |
|
| 查看次数: |
8495 次 |
| 最近记录: |