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 <p...@fleshgrinder.com> 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