Note that there are some explanatory texts on larger screens.

plurals
  1. POPHP: __toString() and json_encode() not playing well together
    primarykey
    data
    text
    <p>I've run into an odd problem and I'm not sure how to fix it. I have several classes that are all PHP implementations of JSON objects. Here' an illustration of the issue</p> <pre><code>class A { protected $a; public function __construct() { $this-&gt;a = array( new B, new B ); } public function __toString() { return json_encode( $this-&gt;a ); } } class B { protected $b = array( 'foo' =&gt; 'bar' ); public function __toString() { return json_encode( $this-&gt;b ); } } $a = new A(); echo $a; </code></pre> <p>The output from this is</p> <pre><code>[{},{}] </code></pre> <p>When the <em>desired</em> output is</p> <pre><code>[{"foo":"bar"},{"foo":"bar"}] </code></pre> <p>The problem is that I was relying on the __toString() hook to do my work for me. But it can't, because the serialize that json_encode() uses won't call __toString(). When it encounters a nested object it simply serializes public properties only.</p> <p>So, the question then become this: Is there a way I can develop a managed interface to JSON classes that both lets me use setters and getters for properties, but also allows me to get the JSON serialization behavior I desire?</p> <p>If that's not clear, here's an example of an implementation that <em>won't</em> work, since the __set() hook is only called for the initial assignment</p> <pre><code>class a { public function __set( $prop, $value ) { echo __METHOD__, PHP_EOL; $this-&gt;$prop = $value; } public function __toString() { return json_encode( $this ); } } $a = new a; $a-&gt;foo = 'bar'; $a-&gt;foo = 'baz'; echo $a; </code></pre> <p>I suppose I could also do something like this</p> <pre><code>class a { public $foo; public function setFoo( $value ) { $this-&gt;foo = $value; } public function __toString() { return json_encode( $this ); } } $a = new a; $a-&gt;setFoo( 'bar' ); echo $a; </code></pre> <p>But then I would have to rely on the diligence of the other developers to use the setters - I can't force adherence programmtically with this solution.</p> <p><strong>---> EDIT &lt;---</strong></p> <p>Now with a test of Rob Elsner's response</p> <pre><code>&lt;?php class a implements IteratorAggregate { public $foo = 'bar'; protected $bar = 'baz'; public function getIterator() { echo __METHOD__; } } echo json_encode( new a ); </code></pre> <p>When you execute this, you can see that the getIterator() method isn't ever invoked.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload