【发布时间】:2010-09-28 22:48:59
【问题描述】:
我遇到了一个奇怪的问题,我不知道如何解决它。我有几个类都是 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;
这个输出是
[{},{}]
当想要的输出是
[{"foo":"bar"},{"foo":"bar"}]
问题是我依靠 __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;
我想我也可以这样做
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;
但是我将不得不依靠其他开发人员的勤奋来使用设置器 - 我无法通过此解决方案以编程方式强制遵守。
---> 编辑
现在测试一下 Rob Elsner 的反应
<?php
class a implements IteratorAggregate
{
public $foo = 'bar';
protected $bar = 'baz';
public function getIterator()
{
echo __METHOD__;
}
}
echo json_encode( new a );
执行此操作时,您可以看到从未调用过 getIterator() 方法。
【问题讨论】:
标签: php json serialization