3v4l.org

run code in 150+ php & hhvm versions
Bugs & Features
<?php class Book { protected $title; protected $author; protected $genres; public function __construct() { $this->genres = new ArrayObject(); } public function addGenre($genre) { $this->genres[] = $genre; return $this; } public function getGenres() { return $this->genres; } public function setAuthor(Person $author) { $this->author = $author; return $this; } public function getAuthor() { return $this->author; } public function setTitle($title) { $this->title = $title; return $this; } public function getTitle() { return $this->title; } } class Person { protected $firstName; protected $lastName; public function setFirstName($firstName) { $this->firstName = $firstName; return $this; } public function getFirstName() { return $this->firstName; } public function setLastName($lastName) { $this->lastName = $lastName; return $this; } public function getLastName() { return $this->lastName; } } interface Hydrator { public function hydrate($object, array $data); public function extract($object); } class ReflectionHydrator implements Hydrator { public function hydrate($object, array $data) { $reflection = new ClassReflection($object); $transform = function ($key) { return 'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key))); }; foreach ($reflection->getMethod() as $method) { if (!$method->isPublic() || 0 !== strpos($method->getName(), 'set')) { continue; } $field = lcfirst(substr($method->getName(), 3)); // @todo } } public function extract($object) { $reflection = new ClassReflection($object); $transform = function ($key) { return '_' . strtolower(array_shift($key)); }; $data = array(); foreach ($reflection->getMethods() as $method) { if (!$method->isPublic() || 0 !== strpos($method->getName(), 'get')) { continue; } $field = lcfirst(substr($method->getName(), 3)); $normalized = preg_replace_callback('/([A-Z])/', $transform, $field); $data[$normalized] = $method->invoke(); } return $array; } } class DryReflectionHydrator implements Hydrator { public function extract($object) { $transform = function ($key) { return '_' . strtolower(array_shift($key)); }; $data = array(); // Process get methods $this->processMethods('get', function ($field, MethodReflection $method) use (&$data, $transform) { $normalized = preg_replace_callback('/([A-Z])/', $transform, $field); $data[$normalized] = $method->invoke(); }); return $data; } public function hydrate($object, array $data) { $transform = function ($key) { return 'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key))); }; $this->processMethods('set', function($field, MethodReflection $method) use ($data, $transform) { $method->invoke(null, $data[$transform($field)]); }); } protected function processMethods($prefix, $callback) { $reflection = new ClassReflection($object); foreach ($reflection->getMethods() as $method) { if (!$method->isPublic() || 0 !== strpos($method->getName(), $prefix)) { continue; } $field = lcfirst(substr($method->getName(), strlen($prefix))); $callback($field, $method); } } } $book = new Book(); $book->setTitle('Harry potter'); $book->addGenre('Drama')->addGenre('Nosense'); $hydrator = new ReflectionHydrator(); var_dump($hydrator->extract($book));
Output for 7.0.0 - 7.1.0
Fatal error: Uncaught Error: Class 'ClassReflection' not found in /in/O5OUB:103 Stack trace: #0 /in/O5OUB(173): ReflectionHydrator->extract(Object(Book)) #1 {main} thrown in /in/O5OUB on line 103
Process exited with code 255.
Output for hhvm-3.12.0
Fatal error: Uncaught Error: Class undefined: ClassReflection in /in/O5OUB:103 Stack trace: #0 /in/O5OUB(173): ReflectionHydrator->extract() #1 {main}
Process exited with code 255.
Output for hhvm-3.10.0
Fatal error: Class undefined: ClassReflection in /in/O5OUB on line 103
Process exited with code 255.
Output for 5.3.0 - 5.6.28
Fatal error: Class 'ClassReflection' not found in /in/O5OUB on line 103
Process exited with code 255.