Hi Richard,
thank you for support with __construct. I absolutely agree that it breaks BC
and fine to propose it just for PHP 8.
By polymorphic dispatch I mean a possibility to have the same method (including
constructor) in multiple variations. E.g.:
class Price
{
public function __construct(int $price)
{
...
}
public function __construct(string $price)
{
...
}
}
Regards,
Tim
> On 12 Jan 2017, at 22:39, Fleshgrinder <[email protected]> wrote:
>
> On 1/12/2017 10:13 PM, Marco Pivetta wrote:
>> Hey Richard,
>>
>> I made an example where everything was in a single class, but most
>> scenarios involve a lazy-loading wrapper that has no knowledge of the
>> original class besides its constructor.
>>
>> I use this approach to generate proxy classes that are "safe" to use with
>> fluent interfaces, for example (because fluent interfaces are really a mess
>> to work with).
>>
>> The alternative (for me, specifically) is to copy the constructor AST into
>> a closure, then store the closure somewhere. Still, if that closure also
>> calls the private constructor, I have to do it recursively, and so on until
>> I just give up :-P Also, this assumes codegen. Large pieces of code will
>> need rewriting, whereas I don't see strong reasoning for dropping a feature
>> that, while weird, is actually useful.
>>
>> Marco Pivetta
>>
>
> That actually calls out for reflection and that's what it is good for.
> Even if explicit construct calls are to be forbidden, the reflection API
> is definitely a different story.
>
> That being said, your remarks definitely tell everyone that a change in
> this area -- if wanted -- is only possible in PHP 8 and has to be
> considered a breaking change.
>
> ```
> <?php
>
> final class DbConnection {
>
> private $dsn;
>
> private $initializer;
>
> public function __construct($dsn) {
> $this->dsn = $dsn;
> // socket stuff happens here, much like with PDO
> }
>
> public static function lazyInstance($dsn) {
> $reflector = new ReflectionClass(self::class);
> $self = $reflector->newInstanceWithoutConstructor();
> $new = $reflector->getConstructor();
>
> $self->initializer = function () use ($self, $new, $dsn) {
> $new->invoke($self, $dsn);
> $self->initializer = function () {};
> };
>
> return $self;
> }
>
> public function query($queryString) {
> $this->initializer->__invoke();
>
> // irrelevant from here on
> return ['query' => $queryString, 'dsn' => $this->dsn];
> }
>
> }
>
> $instance = DbConnection::lazyInstance('mysql://something');
>
> var_dump($instance);
>
> var_dump($instance->query('SELECT * FROM foo'));
> var_dump($instance->query('SELECT * FROM bar'));
> ```
>
> On 1/12/2017 10:34 PM, Tim Bezhashvyly wrote:
>> the only reason for prohibiting explicit __construct calls is that it
>> makes PHP objects mutable and it's state unpredictable. Still would
>> like to give this RFC a try.
>>
>
> I completely share this concern with Tim. Of course reflection would
> still allow one to circumvent any limitations imposed by the normal
> runtime. But that's what reflection is for after all.
>
> On 1/12/2017 10:34 PM, Tim Bezhashvyly wrote:
>> And what about polymorphic dispatch?
>>
>
> I think you need to elaborate a bit more here to get some feedback.
>
> --
> Richard "Fleshgrinder" Fussenegger
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php