3v4l.org

run code in 300+ PHP versions simultaneously
<?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 ReflectionClass($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 ReflectionClass($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, ReflectionMethod $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, ReflectionMethod $method) use ($data, $transform) { $method->invoke(null, $data[$transform($field)]); }); } protected function processMethods($prefix, $callback) { $reflection = new ReflectionClass($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 git.master, git.master_jit, rfc.property-hooks
Fatal error: Uncaught ArgumentCountError: ReflectionMethod::invoke() expects at least 1 argument, 0 given in /in/egl47:115 Stack trace: #0 /in/egl47(115): ReflectionMethod->invoke() #1 /in/egl47(173): ReflectionHydrator->extract(Object(Book)) #2 {main} thrown in /in/egl47 on line 115
Process exited with code 255.

This tab shows result from various feature-branches currently under review by the php developers. Contact me to have additional branches featured.

Active branches

Archived branches

Once feature-branches are merged or declined, they are no longer available. Their functionality (when merged) can be viewed from the main output page


preferences:
48.16 ms | 401 KiB | 8 Q