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

- Thread: https://externals.io/message/16040
- Original archive: https://news-web.php.net/php.internals/16040
- Started by Greg Beaver on 2005-04-20T03:11:46+00:00
- Messages: 7
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #16040 — Greg Beaver — 2005-04-20T03:11:46+00:00

URL: https://externals.io/message/16040#16040

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

---

## #16042 — Marcus Boerger — 2005-04-20T08:06:22+00:00

URL: https://externals.io/message/16040#16042 · In reply to: #16040

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

---

## #16043 — Antony Dovgal — 2005-04-20T08:24:07+00:00

URL: https://externals.io/message/16040#16043 · In reply to: #16040

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

---

## #16044 — Greg Beaver — 2005-04-20T13:52:25+00:00

URL: https://externals.io/message/16040#16044 · In reply to: #16043

Antony Dovgal wrote:

>On Tue, 19 Apr 2005 23:11:46 -0400
>Greg Beaver <cellog@php.net> wrote:
>
>  
>
> > […]
>
>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

---

## #16045 — Johannes Schlueter — 2005-04-20T14:05:35+00:00

URL: https://externals.io/message/16040#16045 · In reply to: #16044

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

---

## #16046 — Greg Beaver — 2005-04-20T14:30:46+00:00

URL: https://externals.io/message/16040#16046 · In reply to: #16045

Johannes Schlueter wrote:
> Hi Greg,
> 
> Greg Beaver wrote:
> 
> 
> > […]
> 
> 
> 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

---

## #16047 — Antony Dovgal — 2005-04-20T14:34:45+00:00

URL: https://externals.io/message/16040#16047 · In reply to: #16044

On Wed, 20 Apr 2005 09:52:25 -0400
Greg Beaver <greg@chiaraquartet.net> wrote:

> Antony Dovgal wrote:
> 
> > […]
> 
> 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
