protected/private function __construct() not allowed in 5.0.4?

php.internals

Greg Beaver

21 years ago
Hi all, I just spent quite a while searching the archives, and can't find any explanation of why this code worked in 5.0.3 but doesn't in 5.0.4: <?php class blah { protected function __construct(){} } ?> Could someone please enlighten me? I was using this for a singleton pattern, and so it would be nice to know why it is so critical for the engine to be anal retentive here. It seems to me that it should be up to the programmer to decide how easily the object can be instantiated, unless there is a deeper engine stability issue. Thanks, Greg

Marcus Boerger

21 years ago
Hello Greg, Wednesday, April 20, 2005, 5:11:46 AM, you wrote:
> Hi all,
> I just spent quite a while searching the archives, and can't find any > explanation of why this code worked in 5.0.3 but doesn't in 5.0.4:
> <?php > class blah { > protected function __construct(){} > }
?>>
> Could someone please enlighten me? I was using this for a singleton > pattern, and so it would be nice to know why it is so critical for the > engine to be anal retentive here. It seems to me that it should be up > to the programmer to decide how easily the object can be instantiated, > unless there is a deeper engine stability issue.
> Thanks, > Greg
At least it works for 5.0.5-dev: marcus@zaphod /usr/src/php-cvs $ php -r 'class T { protected function __construct() {} static function test() { return new T;} } var_dump(T::test());' make: `sapi/cli/php' is up to date. object(T)#1 (0) { } marcus@zaphod /usr/src/php-cvs $ ../PHP_5_0/sapi/cli/php -r 'class T { protected function __construct() {} static function test() { return new T;} } var_dump(T::test());' object(T)#1 (0) { } marcus@zaphod /usr/src/php-cvs $ ../PHP_5_0/sapi/cli/php -v PHP 5.0.5-dev (cli) (built: Apr 7 2005 17:24:12) (DEBUG) Copyright (c) 1997-2004 The PHP Group Zend Engine v2.0.4-dev, Copyright (c) 1998-2004 Zend Technologies but i currently cannot reproduce it with 5.0.4, sorry.
-- Best regards, Marcus mailto:mail@marcus-boerger.de

Antony Dovgal

21 years ago
On Tue, 19 Apr 2005 23:11:46 -0400 Greg Beaver <cellog@php.net> wrote:
> Hi all, > > I just spent quite a while searching the archives, and can't find any > explanation of why this code worked in 5.0.3 but doesn't in 5.0.4: > > <?php > class blah { > protected function __construct(){} > } > ?>
Works fine with HEAD, 5.0.5-dev & 5.0.4. Could you plz explain what did you mean when you said "doesn't work" ?
-- Wbr, Antony Dovgal aka tony2001 antony@zend.com

Greg Beaver

21 years ago
Antony Dovgal wrote:
>On Tue, 19 Apr 2005 23:11:46 -0400 >Greg Beaver <cellog@php.net> wrote: > > > >>Hi all, >> >>I just spent quite a while searching the archives, and can't find any >>explanation of why this code worked in 5.0.3 but doesn't in 5.0.4: >> >><?php >>class blah { >> protected function __construct(){} >>} >>?> >> >> > >Works fine with HEAD, 5.0.5-dev & 5.0.4. >Could you plz explain what did you mean when you said "doesn't work" ? >
I didn't read the error message closely enough - when extending the base class, which has a public constructor, the protected keyword is no longer allowed. <b>Fatal error</b>: Access level to Chiara_PEAR_Server_Frontend_Xmlrpc5_Package ::__construct() must be public (as in class Chiara_XML_RPC5_Server) in <b>c:\php 5\pear\Chiara\PEAR\Server\Frontend\Xmlrpc5.php</b> on line <b>40</b><br /> Try this code (which worked in 5.0.3) <?php class a { public function __construct(){}} class b extends a { protected function __construct(){}} ?> Greg

Johannes Schlueter

21 years ago
Hi Greg, Greg Beaver wrote:
> Try this code (which worked in 5.0.3) > > <?php > class a { public function __construct(){}} > class b extends a { protected function __construct(){}} > ?>
This was changed since such a change of visibility makes no sense - if you extend a class it should still be compatible with it's parent class. johannes
-- Johannes Schlüter Mayflower GmbH / ThinkPHP http://thinkphp.de http://blog.thinkphp.de

Greg Beaver

21 years ago
Johannes Schlueter wrote:
> Hi Greg, > > Greg Beaver wrote: > > >>Try this code (which worked in 5.0.3) >> >><?php >>class a { public function __construct(){}} >>class b extends a { protected function __construct(){}} >>?> > > > This was changed since such a change of visibility makes no sense - if you > extend a class it should still be compatible with it's parent class.
I highly recommend removing this restriction for constructors. The programmer should be the one to determine whether this makes sense. For other methods that are not instance-dependent, this restriction makes perfect sense. most methods can be called by any instance without needing to know what the class is. constructors are not like this. They are tightly bound to the specific class they are in. The same reasoning was used to remove the restrictions on constructor arguments - constructors are not normal methods. I am extending a general purpose XML_RPC server implementation which is designed to be instance based, and making it a singleton. There is nothing wrong with this, and object instances are still 100% compatible. Nobody in their right mind expects to be able to instantiate a child class without knowing anything about it - each class does something unique and possibly incompatible with the base class, otherwise there would be no point in extending the base class. This seems a case of PHP trying to prevent me from doing logic errors without knowing anything about the code, i.e. not in the PHP spirit. Greg

Antony Dovgal

21 years ago
On Wed, 20 Apr 2005 09:52:25 -0400 Greg Beaver <greg@chiaraquartet.net> wrote:
> Antony Dovgal wrote: > > >On Tue, 19 Apr 2005 23:11:46 -0400 > >Greg Beaver <cellog@php.net> wrote: > > > > > > > >>Hi all, > >> > >>I just spent quite a while searching the archives, and can't find any > >>explanation of why this code worked in 5.0.3 but doesn't in 5.0.4: > >> > >><?php > >>class blah { > >> protected function __construct(){} > >>} > >>?> > >> > >> > > > >Works fine with HEAD, 5.0.5-dev & 5.0.4. > >Could you plz explain what did you mean when you said "doesn't work" ? > > > > I didn't read the error message closely enough - when extending the base > class, which has a public constructor, the protected keyword is no > longer allowed. > > <b>Fatal error</b>: Access level to > Chiara_PEAR_Server_Frontend_Xmlrpc5_Package > ::__construct() must be public (as in class Chiara_XML_RPC5_Server) in > <b>c:\php > 5\pear\Chiara\PEAR\Server\Frontend\Xmlrpc5.php</b> on line <b>40</b><br /> > > Try this code (which worked in 5.0.3) > > <?php > class a { public function __construct(){}} > class b extends a { protected function __construct(){}} > ?>
It doesn't work in 5.0.3 too: --------- #./sapi/cli/php -v PHP 5.0.3 (cli) (built: Apr 20 2005 18:26:52) (DEBUG) Copyright (c) 1997-2004 The PHP Group #./sapi/cli/php /www/index.php Fatal error: Access level to b::__construct() must be public (as in class a) in /www/index.php on line 4 --------- As far as I can see this change first appeared somewhere in late 2002, because this patch: http://cvs.php.net/diff.php/ZendEngine2/zend_compile.c?r1=1.337&r2=1.338&ty=u fixes it.
-- Wbr, Antony Dovgal aka tony2001 antony@zend.com