title: Serializing PHP object to JSON
body: <p>So I was wandering around <a href="http://php.net">php.net</a> for information about serializing PHP objects to JSON, when I stumbled across the new <a href="http://www.php.net/manual/en/class.jsonserializable.php">JsonSerializable Interface</a>. It's only <strong>PHP >= 5.4</strong> though, and I'm running in a 5.3.x environment.</p>
  
  <p>How is this sort of functionality achieved <strong>PHP &lt; 5.4</strong>?</p>
  
  <p>I've not worked much with JSON yet, but I'm trying to support an API layer in an application, and dumping the data object (<em>that would otherwise be sent to the view</em>) into JSON would be perfect.</p>
  
  <p>If I attempt to serialize the object directly, it returns an empty JSON string; which is because I assume <code>json_encode()</code> doesn't know what the heck to do with the object. Should I recursively reduce the object into an array, and then encode <em>that</em>?</p>
  
  <hr>
  
  <h1>Example</h1>
  
  <pre><code>$data = new Mf_Data();
  $data-&gt;foo-&gt;bar['hello'] = 'world';
  </code></pre>
  
  <p><strong><code>echo json_encode($data)</code></strong> produces an empty object:</p>
  
  <pre><code>{}
  </code></pre>
  
  <p><strong><code>var_dump($data)</code></strong> however, works as expected:</p>
  
  <pre><code>object(Mf_Data)#1 (5) {
    ["_values":"Mf_Data":private]=&gt;
    array(0) {
    }
    ["_children":"Mf_Data":private]=&gt;
    array(1) {
      [0]=&gt;
      array(1) {
        ["foo"]=&gt;
        object(Mf_Data)#2 (5) {
          ["_values":"Mf_Data":private]=&gt;
          array(0) {
          }
          ["_children":"Mf_Data":private]=&gt;
          array(1) {
            [0]=&gt;
            array(1) {
              ["bar"]=&gt;
              object(Mf_Data)#3 (5) {
                ["_values":"Mf_Data":private]=&gt;
                array(1) {
                  [0]=&gt;
                  array(1) {
                    ["hello"]=&gt;
                    string(5) "world"
                  }
                }
                ["_children":"Mf_Data":private]=&gt;
                array(0) {
                }
                ["_parent":"Mf_Data":private]=&gt;
                *RECURSION*
                ["_key":"Mf_Data":private]=&gt;
                string(3) "bar"
                ["_index":"Mf_Data":private]=&gt;
                int(0)
              }
            }
          }
          ["_parent":"Mf_Data":private]=&gt;
          *RECURSION*
          ["_key":"Mf_Data":private]=&gt;
          string(3) "foo"
          ["_index":"Mf_Data":private]=&gt;
          int(0)
        }
      }
    }
    ["_parent":"Mf_Data":private]=&gt;
    NULL
    ["_key":"Mf_Data":private]=&gt;
    NULL
    ["_index":"Mf_Data":private]=&gt;
    int(0)
  }
  </code></pre>
  
  <hr>
  
  <h1>Addendum</h1>
  
  <h2>1)</h2>
  
  <p>So this is the <code>toArray()</code> function I've devised for the <code>Mf_Data</code> class:</p>
  
  <pre><code>public function toArray()
  {
      $array = (array) $this;
      array_walk_recursive($array, function (&amp;$property) {
          if ($property instanceof Mf_Data) {
              $property = $property-&gt;toArray();
          }
      });
      return $array;
  }
  </code></pre>
  
  <p>However since the <code>Mf_Data</code> objects also have a reference to their parent (<em>containing</em>) object, this fails with recursion. Works like a charm though when I remove the <code>_parent</code> reference.</p>
  
  <h2>2)</h2>
  
  <p>Just to follow up, the final function to transform a complex tree-node object I went with was:</p>
  
  <pre><code>// 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 (&amp;$property) {
          if (is_object($property) &amp;&amp; method_exists($property, 'toArray')) {
              $property = $property-&gt;toArray();
          }
      });
      return $array;
  }
  </code></pre>
  
  <h2>3)</h2>
  
  <p>I'm following up again, with a bit cleaner of an implementation. Using interfaces for an <code>instanceof</code> check seems much cleaner than <code>method_exists()</code> (<em>however <code>method_exists()</code> does cross-cut inheritance/implementation</em>).</p>
  
  <p>Using <code>unset()</code> seemed a bit messy too, and it seems that logic should be refactored into another method. However, this implementation <em>does</em> copy the property array (<em>due to <code>array_diff_key</code></em>), so something to consider.</p>
  
  <pre><code>interface ToMapInterface
  {
  
      function toMap();
  
      function getToMapProperties();
  
  }
  
  class Node implements ToMapInterface
  {
  
      private $index;
      private $parent;
      private $values = array();
  
      public function toMap()
      {
          $array = $this-&gt;getToMapProperties();
          array_walk_recursive($array, function (&amp;$value) {
              if ($value instanceof ToMapInterface) {
                  $value = $value-&gt;toMap();
              }
          });
          return $array;
      }
  
      public function getToMapProperties()
      {
          return array_diff_key(get_object_vars($this), array_flip(array(
              'index', 'parent'
          )));
      }
  
  }
  </code></pre>