3v4l.org

run code in 300+ PHP versions simultaneously
<?php try { $user = new User_DTO(new Validator, [ 'id' => 1, 'name' => 'Foo', 'username' => 'foo', 'email' => '', 'address' => [ 'street' => '', 'suite' => '', 'city' => '', 'zipcode' => '', 'geo' => [ 'lat' => '', 'lng' => '', ], ], 'phone' => '', 'website' => '', 'company' => [ 'name' => '', 'catchPhrase' => '', 'bs' => '', ], ]); $user_list = new User_List_DTO(new Validator, [ 'id' => 2, 'name' => 'Bar', 'username' => 'bar', ]); echo $user->get_id() . PHP_EOL; echo $user->get_name() . PHP_EOL; echo $user->get_username() . PHP_EOL; echo $user_list->get_id() . PHP_EOL; echo $user_list->get_name() . PHP_EOL; echo $user_list->get_username() . PHP_EOL; } catch(Exception $e) { echo $e->getMessage(); } class Validator { public function validate_data_against_schema( array $data, array $schema ) { foreach ( $schema as $key => $requiredType ) { if ( ! array_key_exists( $key, $data ) ) { throw new \UnexpectedValueException( sprintf( 'Required key "%s" does not exist.', $key ) ); } if ( is_array($requiredType) ) { if ( ! is_array( $data[ $key ] ) ) { throw new \UnexpectedValueException( sprintf( 'Key "%s" must be an array, %s provided.', $key, gettype( $data[ $key ] ) ) ); } // Traverse down the children, recursively. $this->validate_data_against_schema( $data[ $key ], $requiredType ); } else { if ( gettype( $data[ $key ] ) !== $requiredType ) { throw new \UnexpectedValueException( sprintf( 'Key "%s" must be of type %s, %s provided.', $key, $requiredType, gettype( $data[ $key ] ) ) ); } } } } } abstract class DTO { abstract protected function getSchema(): array; abstract protected function initaliseFromArray($array): void; final public function __construct( Validator $validator, array $data ) { $validator->validate_data_against_schema( $data, $this->getSchema() ); } } class User_DTO extends DTO { private int $id; private string $name; private string $username; protected function getSchema(): array { return [ 'id' => 'integer', 'name' => 'string', 'username' => 'string', 'email' => 'string', 'address' => [ 'street' => 'string', 'suite' => 'string', 'city' => 'string', 'zipcode' => 'string', 'geo' => [ 'lat' => 'float', 'lng' => 'float', ], ], 'phone' => 'string', 'website' => 'string', 'company' => [ 'name' => 'string', 'catchPhrase' => 'string', 'bs' => 'string', ], ]; } protected function initaliseFromArray($array): void { $this->id = (int) $this->data['id']; $this->name = (string) $this->data['name']; $this->username = (string) $this->data['username']; } public function get_id(): int { return $this->id; } public function get_name(): string { return $this->name; } public function get_username(): string { return $this->username; } // etc } class User_List_DTO extends DTO { protected function getSchema(): array { return [ 'id' => 'integer', 'name' => 'string', 'username' => 'string', ]; } protected function initaliseFromArray($array): void { $this->id = (int) $this->data['id']; $this->name = (string) $this->data['name']; $this->username = (string) $this->data['username']; } public function get_id(): int { return $this->id; } public function get_name(): string { return $this->name; } public function get_username(): string { return $this->username; } }
Output for git.master, git.master_jit, rfc.property-hooks
Key "lat" must be of type float, string provided.

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:
62 ms | 401 KiB | 8 Q