On Sat, Oct 15, 2022, at 6:18 AM, Gianni Gentile wrote:
> Hi,
>
> in my every day experience, using custom DTO classes and different API, 
> I often write code to instantiate my objects from associative arrays.
>
> What are your thoughts on introduce the `(AnyType)` cast to instantiate 
> objects from associative array (or object properties also)?
>
> In my proposal, if AnyType implements __set_state(), casting should be 
> syntactic sugar for:
>
>      AnyType::_set_state((array) $data)
>
> just for (useless) example, consider DateTime or DateTimeImmutable (both 
> have __set_state() implementation); when applied to objects of that 
> type, we can write:
>
>      $dt = new DateTime();
>
>      $dtArray = (array) $dt; // 3 elements array
>
>      $copyOfDt = (DateTime) $dtArray; // or simply $copyOfDt = 
> (DateTime) $dt;
>
> In case AnyType does not implements __set_state(), casting should create 
> a new instance, assigning values to properties, taken from array values 
> with corresponding key (in a similar way class objects are created when 
> row is fetched from database specifying PDO_FETCH_CLASS) eventually 
> invoking __set() magic method for properties not declared;
>
> In this scenario,
>
>      (object) ['one' => 1, 'two' => 2]
>
> and
>
>      (StdClass) ['one' => 1, 'two' => 2]
>
> do exactly the same work.
>
>
> Reasons:
>
> - clear code
>
> - array to object conversion (casting) would be the simmetrical 
> counterpart of object to array conversion

Most DTOs have a 1:1 match from constructor to properties.  In current PHP 
versions, that means they often look like this:

class Point
{
    public function __construct(
        public readonly int $x,
        public readonly int $y,
        public readonly int $z,
    ) {}
}

Which means, in current PHP versions, you can use named args and splat to 
create one from an array.

$data = ['x' => 1, 'y' => 2, 'z' => 3];

$point = new Point(...$data);

No casting necessary.

True, that's not true of all such classes, but certainly the plurality.  In the 
cases where it's not, an explicit named constructor (via a Trait or otherwise) 
is a more self-documenting approach.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to