<?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;
}
}
preferences:
45.13 ms | 402 KiB | 5 Q