Json_encode for a class with magic properties

I am trying an json_encodearray of objects that have magical properties using __getand __set. json_encodecompletely ignores them, the result is an array of empty objects (all normal properties privateor protected).

So imagine this class:

class Foo
{
    public function __get($sProperty)
    {
        if ($sProperty == 'foo')
        {
            return 'bar!';
        }
        return null;
    }
}

$object = new Foo();
echo $object->foo; // echoes "foo"
echo $object->bar; // warning
echo json_encode($object); // "{}"

I tried to implement IteratorAggregateand Serializablefor the class, but json_encodestill can not see my magical properties. Since I'm trying to encode an array of these objects, the method AsJSON()in the class will not work either.

Refresh! The question seems easy to misunderstand. How can I say json_encodewhich “magical properties” exist? IteratorAggregatedoes not work.

BTW: PHP " ". , , .

+5
8

json_encode() "" . HashTable, , obj- > get_properties(). ( , , Traversable, Iterator ..) HashTable , . . static void json_encode_array() ext/json/json.c
json_encode(), $obj- > propname.

edit: " ",

interface EncoderData {
  public function getData();
}

function json_encode_ex_as_array(array $v) {
  for($i=0; $i<count($v); $i++) {
    if ( !isset($v[$i]) ) {
      return false;
    }
  }
  return true;
}

define('JSON_ENCODE_EX_SCALAR', 0);
define('JSON_ENCODE_EX_ARRAY', 1);
define('JSON_ENCODE_EX_OBJECT', 2);
define('JSON_ENCODE_EX_EncoderDataObject', 3);

function json_encode_ex($v) {
  if ( is_object($v) ) {
    $type = is_a($v, 'EncoderData') ? JSON_ENCODE_EX_EncoderDataObject : JSON_ENCODE_EX_OBJECT;
  }
  else if ( is_array($v) ) {
    $type = json_encode_ex_as_array($v) ? JSON_ENCODE_EX_ARRAY : JSON_ENCODE_EX_OBJECT;
  }
  else {
    $type = JSON_ENCODE_EX_SCALAR;
  }

  switch($type) {
    case JSON_ENCODE_EX_ARRAY: // array [...]
      foreach($v as $value) {
        $rv[] = json_encode_ex($value);
      }
      $rv = '[' . join(',', $rv) . ']';
      break;
    case JSON_ENCODE_EX_OBJECT: // object { .... }
      $rv = array();
      foreach($v as $key=>$value) {
        $rv[] = json_encode((string)$key) . ':' . json_encode_ex($value);
      }
      $rv = '{' . join(',', $rv) .'}';
      break;
    case JSON_ENCODE_EX_EncoderDataObject:
      $rv = json_encode_ex($v->getData());
      break;
    default:
      $rv = json_encode($v);
  }
  return $rv;
}

class Foo implements EncoderData {
  protected $name;
  protected $child;

  public function __construct($name, $child) {
    $this->name = $name;
    $this->child = $child;

  }
  public function getData() {
    return array('foo'=>'bar!', 'name'=>$this->name, 'child'=>$this->child);
  }
}


$data = array();
for($i=0; $i<10; $i++) {
  $root = null;
  foreach( range('a','d') as $name ) {
    $root = new Foo($name, $root);
  }
  $data[] = 'iteration '.$i;
  $data[] = $root;
  $root = new StdClass;
  $root->i = $i;
  $data[] = $root;
}
$json = json_encode_ex($data);
echo $json, "\n\n\n";
$data = json_decode($json);
var_dump($data);

: , .

$obj = new StdClass;
$obj->x = new StdClass;
$obj->x->y = $obj;
echo json_encode($obj); // warning: recursion detected...
echo json_encode_ex($obj); // this one runs until it hits the memory limit
+3

PHP 5.4 JsonSerializable. , jsonSerialize, . .

+24

:

, . - Vegard Larsen 1

 

, .

 

, .

 

$obj- > foo

 

PHP, , "", $obj->foo.

, , json_encode .

, json_encode , __get , , .

+5

, , , / PHP JSON, .

__get __set , . , .

, foo/bar JSON, , , . .

- :

($ name, $value) {    $ this- > data [$ name] = $value; }

, :

$foo = new ObjectClass; $ Foo- > ( 'Foo', '');

$data ['foo'] = 'bar' json_encode , .

json_encode , . . , __get, , "" "foo".

, , , . json_encoding . -, , , , .

, , , , IMO, .

+2

.

class Foo
{
    private $prop = array();

    public function __get($sProperty)
    {
       return $this->prop[$sProperty];
    }

    public function __set($sProperty, $value)
    {
       $this->prop[$sProperty] = $value;
    }

    public function getJson(){
        return json_encode($this->prop);
    }
}



$f = new Foo();
$f->foo = 'bar';
$json = $f->getJson();
+1


JSON , - , .

0

?

$object = new Foo();
echo $object->foo; // how do you know to access foo and not oof?
                   // how do you expect json_encode to know to access foo?

- , , . .

echo json_encode($object); // "{}"

, , $object , ()

0

I found the following that worked for me creating classes with dynamic properties and outputting them using json_encode. Maybe this helps other people.

http://krisjordan.com/dynamic-properties-in-php-with-stdclass

0
source

All Articles