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 7.4.0 - 7.4.33, 8.0.0 - 8.0.30, 8.1.0 - 8.1.28, 8.2.0 - 8.2.18, 8.3.0 - 8.3.4, 8.3.6
Key "lat" must be of type float, string provided.
Output for 8.3.5
Warning: PHP Startup: Unable to load dynamic library 'sodium.so' (tried: /usr/lib/php/8.3.5/modules/sodium.so (libsodium.so.23: cannot open shared object file: No such file or directory), /usr/lib/php/8.3.5/modules/sodium.so.so (/usr/lib/php/8.3.5/modules/sodium.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 Key "lat" must be of type float, string provided.
Output for 7.2.0 - 7.2.33, 7.3.0 - 7.3.33
Parse error: syntax error, unexpected 'int' (T_STRING), expecting function (T_FUNCTION) or const (T_CONST) in /in/b8nFS on line 89
Process exited with code 255.

preferences:
166.33 ms | 402 KiB | 181 Q