PHP: __toString() and json_encode() not playing well together

后端 未结 5 1922
故里飘歌
故里飘歌 2021-02-07 14:31

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

5条回答
  •  臣服心动
    2021-02-07 15:23

    In PHP > v5.4.0 you can implement the interface called JsonSerializable as described in the answer by Tivie.

    For those of us using PHP < 5.4.0 you can use a solution which employs get_object_vars() from within the object itself and then feeds those to json_encode(). That is what I have done in the following example, using the __toString() method, so that when I cast the object as a string, I get a JSON encoded representation.

    Also included is an implementation of the IteratorAggregate interface, with its getIterator() method, so that we can iterate over the object properties as if they were an array.

     TRUE);
      
      /**
       * Retrieve the object as a JSON serialized string
       *
       * @return string
       */
      public function __toString() {
        $properties = $this->getAllProperties();
    
        $json = json_encode(
          $properties,
          JSON_FORCE_OBJECT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT
        );
    
        return $json;
      }
    
      /**
       * Retrieve an external iterator
       *
       * @link http://php.net/manual/en/iteratoraggregate.getiterator.php
       * @return \Traversable
       *  An instance of an object implementing \Traversable
       */
      public function getIterator() {
        $properties = $this->getAllProperties();
        $iterator = new \ArrayIterator($properties);
    
        return $iterator;
      }
    
      /**
       * Get all the properties of the object
       *
       * @return array
       */
      private function getAllProperties() {
        $all_properties = get_object_vars($this);
    
        $properties = array();
        while (list ($full_name, $value) = each($all_properties)) {
          $full_name_components = explode("\0", $full_name);
          $property_name = array_pop($full_name_components);
          if ($property_name && isset($value)) $properties[$property_name] = $value;
        }
    
        return $properties;
      }
    
    }
    
    $o = new TestObject();
    
    print "JSON STRING". PHP_EOL;
    print "------" . PHP_EOL;
    print strval($o) . PHP_EOL;
    print PHP_EOL;
    
    print "ITERATE PROPERTIES" . PHP_EOL;
    print "-------" . PHP_EOL;
    foreach ($o as $key => $val) print "$key -> $val" . PHP_EOL;
    print PHP_EOL;
    
    ?>
    

    This code produces the following output:

    JSON STRING
    ------
    {"public":"foo","protected":"bar","private":1,"privateList":{"0":"foo","1":"bar","baz":true}}
    
    ITERATE PROPERTIES
    -------
    public -> foo
    protected -> bar
    private -> 1
    privateList -> Array
    

提交回复
热议问题