On 21/10/2020 10:47, Pierre wrote:
I'd recommend that if your data is arbitrary, you can use arrays, if you
it's not, you probably always should write typed value objects


This is pretty much what I was going to say. If you have truly dynamic keys, then having the full set of array functions available - e.g. array_map, array_filter, all the variations of sort - is almost definitely a win. If you know the property names in advance, then defining them on a class is going to help you catch a lot of mistakes.


On 21/10/2020 10:38, Björn Larsson wrote:
One typical usecase we have is populating an object with the result
from a DB query or using an object to write to a DB.


This is certainly common, and even has a built-in mode in PDO. However, I suspect that if we didn't have stdClass, we would no longer see the need to add it just for these use cases, because they could use an anonymous class instead.

Which brings me back to the feature request: what if rather than stdClass, we look for a better syntax for creating and populating anonymous class instances? Then you could start with a literal and add real object behaviour to it - add methods, implement an interface, constrain the type of properties, etc.

I think there are two problems we might want to solve there:

1. The only way to initialise the object with variables from the outer scope is to pass them to a constructor, which is a bit messy (although constructor property promotion improves things a bit, see example below). 2. There's no way to create a truly dynamic class, i.e. one with some or all properties determined at run-time, without extensive string manipulation and eval(). (Although you can simply write "$object = new class{}; $object->foo=42;" to add a public, untyped property).

The proposed syntax would help with (1), but not really with (2), since you need to know at least the _number_ of properties in order to write out the literal.


Examples, and some probably bad ideas, in the hope they inspire someone to better ideas:

// 7.4
$object = new class($foo, $foo * 2, $nextBaz) {
    public int $foo;
    public int $bar;
    public int $baz;
    public function __construct($foo, $bar, $baz) {
          $this->foo=$foo;
          $this->bar=$bar;
          $this->baz=$baz;
    }
};

// 8.0
$object = new class($foo, $foo * 2, $nextBaz) {
    public function __construct(public int $foo, public int $bar, public int $baz) {}
};

// Promote properties into named parameters, implicitly defining a constructor and passing them to it? $object = new class(public int foo: $foo, public int bar: $foo * 2, public int baz: $nextBaz) {};

// Extend this to accept an array spread? Means all properties have to have the same visibility and type, or default to "public mixed"... $data = ['foo' => 42, 'bar' => 84, 'baz' => 69]; // dynamic data, e.g. a DB result set row
$object = new class(public int ...$data) {};


Regards,

--
Rowan Tommins (né Collins)
[IMSoP]

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

Reply via email to