<?php
try {
$user_data = json_encode( [
'id' => 'a2aa06d9-b3b6-4f8c-a450-a5a37f401ff4',
'name' => 42,
'username' => (float)'NaN',
'email' => true,
'address' => [
'street' => false,
'suite' => M_PI,
'city' => 1.5,
'zipcode' => 'The back of beyond',
'geo' => [
'lat' => 'https://3v4l.org',
'lng' => 'looooong',
],
],
'phone' => 'E.T. Phone Home',
'website' => 0,
'company' => [
'name' => 1.5,
'catchPhrase' => false,
'bs' => true,
],
], JSON_PRETTY_PRINT );
echo $user_data . PHP_EOL;
$user_data = json_decode( $user_data, true );
$user = new User_DTO($user_data);
$user_list = new User_List_DTO([
'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();
}
abstract class DTO {
protected $data = [];
protected $schema = [];
public function __construct( array $data ) {
$this->validate_data_against_schema( $data, $this->schema );
$this->data = $data;
}
private function validate_data_against_schema( array $data, array $schema ) {
foreach ( $schema as $key => $value ) {
if ( ! array_key_exists( $key, $data ) ) {
throw new \UnexpectedValueException( sprintf( 'Required key "%s" does not exist.', $key ) );
}
// We don't want to enforce any specific type, but if we
// expect a scalar, we don't want an array.
if ( is_scalar( $value ) && ! is_scalar( $data[ $key ] ) ) {
throw new \UnexpectedValueException( sprintf(
'Key "%s" must be scalar, %s provided.',
$key,
gettype( $data[ $key ] )
) );
}
// Same the other way around. If we expect an array,
// we don't want anything else.
if ( is_array( $value ) && ! 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.
if ( is_array( $value ) ) {
$this->validate_data_against_schema( $data[ $key ], $value );
}
}
}
}
class User_DTO extends DTO {
protected $schema = [
'id' => '',
'name' => '',
'username' => '',
'email' => '',
'address' => [
'street' => '',
'suite' => '',
'city' => '',
'zipcode' => '',
'geo' => [
'lat' => '',
'lng' => '',
],
],
'phone' => '',
'website' => '',
'company' => [
'name' => '',
'catchPhrase' => '',
'bs' => '',
],
];
public function get_id(): string {
return (string) $this->data['id'];
}
public function get_name(): string {
return (string) $this->data['name'];
}
public function get_username(): string {
return (string) $this->data['username'];
}
// etc
}
class User_List_DTO extends DTO {
protected $schema = [
'id' => '',
'name' => '',
'username' => '',
];
public function get_id(): string {
return (string) $this->data['id'];
}
public function get_name(): string {
return (string) $this->data['name'];
}
public function get_username(): string {
return (string) $this->data['username'];
}
}
preferences:
30.9 ms | 402 KiB | 5 Q