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

Reply via email to