3v4l.org

run code in 150+ php & hhvm versions
Bugs & Features
<?php class OpenStruct extends ArrayObject { public function __construct($input = array()) { parent::__construct($input, static::ARRAY_AS_PROPS); } public function offsetSet($key, $value) { if (is_array($value)) { parent::offsetSet($key, new static($value)); } else { parent::offsetSet($key, $value); } } public function offsetGet($key) { $raw = parent::offsetGet($key); if (is_callable($raw)) { return call_user_func($raw); } return $raw; } public function __call($method, $args) { $raw = parent::offsetGet($method); if (is_callable($raw)) { if (version_compare(PHP_VERSION, '5.4.0', '>=') && $raw instanceof \Closure) { $raw->bindTo($this); } return call_user_func_array($raw, $args); } } static public function fromJson($json) { if (! is_string($json)) { throw new InvalidArgumentException('Argument must be a string.'); } $input = json_decode($json, true); if (null === $input) { throw new InvalidArgumentException('Argument must be a string containing valid JSON.'); } return new static($input); } } class Struct extends OpenStruct { public function __construct($input) { parent::__construct($input); } public function offsetSet($key, $value) { if (! $this->offsetExists($key)) { throw new RuntimeException(sprintf('Undefined field "%s"', $key)); } parent::offsetSet($key, $value); } public function offsetGet($key) { if (! $this->offsetExists($key)) { throw new RuntimeException(sprintf('Undefined field "%s"', $key)); } parent::offsetGet($key); } public function offsetUnset($key) { throw new RuntimeException(sprintf('Cannot unset field "%s"', $key)); } } // OpenStruct with Constructor Parameters // Cannot Change Structure $person = new OpenStruct(array('first' => 'Joe', 'last' => 'Bloggs', 'age' => 20)); // Nested Array becomes OpenStruct $person->address = array( 'address' => '123 Alphabet Street', 'city' => 'Awesome City', 'postcode' => 'ABC 123', 'country' => 'Awesome Country' ); $person->first; // $person['first']; $person->last; // $person['last']; $person->age; // $person['age']; $person->address->city; // $person['address']['city']; // Nested OpenStruct $person->hobbies = new OpenStruct(array('Football', 'Ice Hockey', 'Formula 1')); // Traversable foreach ($person->hobbies as $hobby) { echo 'Hobby: ' . $hobby . "\n"; } // Convert to JSON echo 'JSON: ' . $person->toJson() . "\n"; print_r($person); // OpenStruct with no Constructor $person = new OpenStruct; $person->name = 'Joe'; $person['name'] = 'John'; print_r($person); // Struct Requires Constructor Parameters // Cannot Change Structure try { $person = new Struct(array('first' => 'Joe', 'last' => 'Bloggs', 'hobbies' => array('Football', 'Ice Hockey', 'Formula 1'))); print_r($person); $person->age = 30; } catch (RuntimeException $e) { echo 'Cannot change Struct' . "\n"; } // OpenStruct from JSON String // Can Change Structure $json = OpenStruct::fromJson('{"first":"Joe","last":"Bloggs","age":20,"address":{"address":"123 Alphabet Street","city":"Awesome City","postcode":"ABC 123","country":"Canada"}}'); $json->foo = 'bar'; print_r($json); // Struct from JSON String // Cannot Change Structure try { $json = Struct::fromJson('{"first":"Joe","last":"Bloggs","age":20,"address":{"address":"123 Alphabet Street","city":"Awesome City","postcode":"ABC 123","country":"Canada"}}'); print_r($json); $json->foo = 'bar'; } catch (RuntimeException $e) { echo 'Cannot change Struct' . "\n"; } // OpenStructs with Closures $open = new OpenStruct; $open->first = 'Joe'; $open->last = 'Bloggs'; $open->fullName = function() use ($open) { return $open->first . ' ' . $open->last; }; /* // PHP 5.4 Style $open->fullName = function() { return $this->first . ' ' . $this->last; }; */ $open->last = 'Smith'; print_r($open->fullName()); // OpenStruct from Object $object = new StdClass; $object->first = 'Joe'; $object->last = 'Bloggs'; $open = new OpenStruct($object); $open->first; print_r($open); // Struct from Object $object = new StdClass; $object->first = 'Joe'; $object->last = 'Bloggs'; try { $open = new Struct($object); print_r($open); $open->age = 30; } catch (RuntimeException $e) { echo 'Cannot change Struct' . "\n"; }
Output for 5.4.8 - 7.1.0
Hobby: Football Hobby: Ice Hockey Hobby: Formula 1 Notice: Undefined index: toJson in /in/hFIGn on line 30 JSON: OpenStruct Object ( [storage:ArrayObject:private] => Array ( [first] => Joe [last] => Bloggs [age] => 20 [address] => OpenStruct Object ( [storage:ArrayObject:private] => Array ( [address] => 123 Alphabet Street [city] => Awesome City [postcode] => ABC 123 [country] => Awesome Country ) ) [hobbies] => OpenStruct Object ( [storage:ArrayObject:private] => Array ( [0] => Football [1] => Ice Hockey [2] => Formula 1 ) ) ) ) OpenStruct Object ( [storage:ArrayObject:private] => Array ( [name] => John ) ) Struct Object ( [storage:ArrayObject:private] => Array ( [first] => Joe [last] => Bloggs [hobbies] => Array ( [0] => Football [1] => Ice Hockey [2] => Formula 1 ) ) ) Cannot change Struct OpenStruct Object ( [storage:ArrayObject:private] => Array ( [first] => Joe [last] => Bloggs [age] => 20 [address] => Array ( [address] => 123 Alphabet Street [city] => Awesome City [postcode] => ABC 123 [country] => Canada ) [foo] => bar ) ) Struct Object ( [storage:ArrayObject:private] => Array ( [first] => Joe [last] => Bloggs [age] => 20 [address] => Array ( [address] => 123 Alphabet Street [city] => Awesome City [postcode] => ABC 123 [country] => Canada ) ) ) Cannot change Struct Joe SmithOpenStruct Object ( [storage:ArrayObject:private] => stdClass Object ( [first] => Joe [last] => Bloggs ) ) Struct Object ( [storage:ArrayObject:private] => stdClass Object ( [first] => Joe [last] => Bloggs ) ) Cannot change Struct
Output for 5.3.0 - 5.4.7
Hobby: Football Hobby: Ice Hockey Hobby: Formula 1 Notice: Undefined index: toJson in /in/hFIGn on line 30 JSON: OpenStruct Object ( [storage:ArrayObject:private] => Array ( [first] => Joe [last] => Bloggs [age] => 20 [address] => OpenStruct Object ( [storage:ArrayObject:private] => Array ( [address] => 123 Alphabet Street [city] => Awesome City [postcode] => ABC 123 [country] => Awesome Country ) ) [hobbies] => OpenStruct Object ( [storage:ArrayObject:private] => Array ( [0] => Football [1] => Ice Hockey [2] => Formula 1 ) ) ) ) OpenStruct Object ( [storage:ArrayObject:private] => Array ( [name] => John ) ) Struct Object ( [storage:ArrayObject:private] => Array ( [first] => Joe [last] => Bloggs [hobbies] => Array ( [0] => Football [1] => Ice Hockey [2] => Formula 1 ) ) ) Cannot change Struct OpenStruct Object ( [storage:ArrayObject:private] => Array ( [first] => Joe [last] => Bloggs [age] => 20 [address] => Array ( [address] => 123 Alphabet Street [city] => Awesome City [postcode] => ABC 123 [country] => Canada ) [foo] => bar ) ) Struct Object ( [storage:ArrayObject:private] => Array ( [first] => Joe [last] => Bloggs [age] => 20 [address] => Array ( [address] => 123 Alphabet Street [city] => Awesome City [postcode] => ABC 123 [country] => Canada ) ) ) Cannot change Struct Joe SmithOpenStruct Object ( [storage:ArrayObject:private] => stdClass Object ( [first] => Joe [last] => Bloggs ) ) Struct Object ( [storage:ArrayObject:private] => stdClass Object ( [first] => Joe [last] => Bloggs ) ) Cannot change Struct