# BC break with php 5.2.6

- Thread: https://externals.io/message/36606
- Original archive: https://news-web.php.net/php.internals/36606
- Started by Marco Kaiser on 2008-03-27T08:25:48+00:00
- Messages: 13
- 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

---

## #36606 — Marco Kaiser — 2008-03-27T08:25:48+00:00

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

Hi,

i noticed that some changes was made that 100% break all apps that do such
stuff:

class x extends y
{
    public static function foo()
    {
        new self();
    }
}

class y
{
    private function __construct()
    {
        echo 'y::__construct()' . PHP_EOL;
    }
}

x::foo();

with php 5.2.5 i works so that i get an output "y::__construct()" but with
5.2.6RC and -DEV
it throws an fatal error:

Fatal error: Call to private y::__construct() from context 'x'

i can remember that i asked a related question last year and someone told me
it is ok so and its a know behavior.
This change will ie. break ZF too. Any suggestions to this behavior?

-- 
Marco Kaiser

---

## #36607 — Lokrain — 2008-03-27T08:44:56+00:00

URL: https://externals.io/message/36606#36607 · In reply to: #36606

Hello Marco,

May be you should check the "[PHP-DEV] Inconsistencies when accessing
protected members" thread.

It's said there:

Private means this API belongs to this class only, protected means this API
> belongs to this class and the children.


and you can find there a lot of useful thoughts about your question there.

---

## #36609 — Marcus Boerger — 2008-03-27T09:50:33+00:00

URL: https://externals.io/message/36606#36609 · In reply to: #36606

Hello Marco,

Thursday, March 27, 2008, 9:25:48 AM, you wrote:

> Hi,

> i noticed that some changes was made that 100% break all apps that do such
> stuff:

> class x extends y
> {
>     public static function foo()
>     {
>         new self();
>     }
> }

> class y
> {
>     private function __construct()
>     {
>         echo 'y::__construct()' . PHP_EOL;
>     }
> }

> x::foo();

> with php 5.2.5 i works so that i get an output "y::__construct()" but with
> 5.2.6RC and -DEV
> it throws an fatal error:

> Fatal error: Call to private y::__construct() from context 'x'

The behavior is correct. Maybe something with $this is broken in earlier
versions. I checked the basic issue here calling an inherited private
constructor directly without anything else involved:

[marcus@zaphod PHP_5_0]$ php -r 'class R{private function __construct(){}} class D extends R{} new D;'
make: `sapi/cli/php' is up to date.

Fatal error: Call to private R::__construct() from context '' in Command line code on line 1
[marcus@zaphod PHP_5_0]$ cd ../PHP_5_1
[marcus@zaphod PHP_5_1]$ php -r 'class R{private function __construct(){}} class D extends R{} new D;'
make: `sapi/cli/php' is up to date.

Fatal error: Call to private R::__construct() from context '' in Command line code on line 1
[marcus@zaphod PHP_5_1]$ cd ../PHP_5_2
[marcus@zaphod PHP_5_2]$ php -r 'class R{private function __construct(){}} class D extends R{} new D;'
make: `sapi/cli/php' is up to date.

Fatal error: Call to private R::__construct() from invalid context in Command line code on line 1
[marcus@zaphod PHP_5_2]$ cd ../PHP_5_3
[marcus@zaphod PHP_5_3]$ php -r 'class R{private function __construct(){}} class D extends R{} new D;'
make: `sapi/cli/php' is up to date.

Fatal error: Call to private R::__construct() from invalid context in Command line code on line 1
[marcus@zaphod php-cvs]$ cd ../php-cvs
[marcus@zaphod php-cvs]$ php -r 'class R{private function __construct(){}} class D extends R{} new D;'
make: `sapi/cli/php' is up to date.

Fatal error: Call to private R::__construct() from invalid context in Command line code on line 1

Apparently all of 5.0, 5.1, 5.2, 5.3 and HEAD behave in the same way and issue a
Fatal error as expected.

Now your code uses self winthin class X which is derived from Y which has a
private constructor. Let's see whether the ctor is illegally called in this
example:

[marcus@zaphod PHP_5_0]$ cd ../PHP_5_0
[marcus@zaphod PHP_5_0]$ php -r 'class R{private function __construct(){echo "R\n";}} class D extends R{static function f(){var_dump(new self);}} D::f();'
make: `sapi/cli/php' is up to date.
R
object(D)#1 (0) {
}
[marcus@zaphod PHP_5_0]$ cd ../PHP_5_1
[marcus@zaphod PHP_5_1]$ php -r 'class R{private function __construct(){echo "R\n";}} class D extends R{static function f(){var_dump(new self);}} D::f();'
make: `sapi/cli/php' is up to date.
R
object(D)#1 (0) {
}
[marcus@zaphod PHP_5_1]$ cd ../PHP_5_2
[marcus@zaphod PHP_5_2]$ php -r 'class R{private function __construct(){echo "R\n";}} class D extends R{static function f(){var_dump(new self);}} D::f();'
make: `sapi/cli/php' is up to date.

Fatal error: Call to private R::__construct() from context 'D' in Command line code on line 1

So yes, there is a bug with the inheritance rules in older versions.

> i can remember that i asked a related question last year and someone told me
> it is ok so and its a know behavior.
> This change will ie. break ZF too. Any suggestions to this behavior?

Fix the code by finding the correct way that works with both old and new
versions.

Best regards,
 Marcus

---

## #36613 — Marco Kaiser — 2008-03-27T13:08:32+00:00

URL: https://externals.io/message/36606#36613 · In reply to: #36609

Hi Marcus,

thanks for this conclusion. I just asked this because this changed in this
release and should noticed in the readme or upgrade process because most
singleton pattern implementations in some frameworks, for ie. ZF are using
this code:

class My_Controller_Front extends Zend_Controller_Front
{
    public static function getInstance()
    {
        if (null === self::$_instance) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }
}

The __constructor in Zend_Controller_Front is private.
I asked a, i think, similar question last nov. About private properties.
http://news.php.net/php.internals/33543

Johannes replied to this:

http://news.php.net/php.internals/33544

Johannes: " That's a feature: Extended classes know nothing about private
stuff in
the parent class. Without that the encapsulation won't be complete."

This means this "was maybe a bug, that i allread talked about" but its now
changed so we should raise a notice about this. That will BREAK
Many many apps out there.

For example, PHPUNIT, ZendFramework, ezComponents.

-- Marco

> -----Original Message-----
> From: Marcus Boerger [mailto:helly@php.net]
> Sent: Thursday, March 27, 2008 10:51 AM
> To: Marco Kaiser
> Cc: PHP Developers Mailing List; php-qa@lists.php.net
> Subject: Re: [PHP-QA] BC break with php 5.2.6
> 
> Hello Marco,
> 
> Thursday, March 27, 2008, 9:25:48 AM, you wrote:
> 
> > […]
> 
> > […]
> such
> > […]
> 
> > […]
> 
> > […]
> 
> > […]
> 
> > […]
> with
> > […]
> 
> > […]
> 
> The behavior is correct. Maybe something with $this is broken in
> earlier
> versions. I checked the basic issue here calling an inherited private
> constructor directly without anything else involved:
> 
> [marcus@zaphod PHP_5_0]$ php -r 'class R{private function
> __construct(){}} class D extends R{} new D;'
> make: `sapi/cli/php' is up to date.
> 
> Fatal error: Call to private R::__construct() from context '' in
> Command line code on line 1
> [marcus@zaphod PHP_5_0]$ cd ../PHP_5_1
> [marcus@zaphod PHP_5_1]$ php -r 'class R{private function
> __construct(){}} class D extends R{} new D;'
> make: `sapi/cli/php' is up to date.
> 
> Fatal error: Call to private R::__construct() from context '' in
> Command line code on line 1
> [marcus@zaphod PHP_5_1]$ cd ../PHP_5_2
> [marcus@zaphod PHP_5_2]$ php -r 'class R{private function
> __construct(){}} class D extends R{} new D;'
> make: `sapi/cli/php' is up to date.
> 
> Fatal error: Call to private R::__construct() from invalid context in
> Command line code on line 1
> [marcus@zaphod PHP_5_2]$ cd ../PHP_5_3
> [marcus@zaphod PHP_5_3]$ php -r 'class R{private function
> __construct(){}} class D extends R{} new D;'
> make: `sapi/cli/php' is up to date.
> 
> Fatal error: Call to private R::__construct() from invalid context in
> Command line code on line 1
> [marcus@zaphod php-cvs]$ cd ../php-cvs
> [marcus@zaphod php-cvs]$ php -r 'class R{private function
> __construct(){}} class D extends R{} new D;'
> make: `sapi/cli/php' is up to date.
> 
> Fatal error: Call to private R::__construct() from invalid context in
> Command line code on line 1
> 
> Apparently all of 5.0, 5.1, 5.2, 5.3 and HEAD behave in the same way
> and issue a
> Fatal error as expected.
> 
> Now your code uses self winthin class X which is derived from Y which
> has a
> private constructor. Let's see whether the ctor is illegally called in
> this
> example:
> 
> [marcus@zaphod PHP_5_0]$ cd ../PHP_5_0
> [marcus@zaphod PHP_5_0]$ php -r 'class R{private function
> __construct(){echo "R\n";}} class D extends R{static function
> f(){var_dump(new self);}} D::f();'
> make: `sapi/cli/php' is up to date.
> R
> object(D)#1 (0) {
> }
> [marcus@zaphod PHP_5_0]$ cd ../PHP_5_1
> [marcus@zaphod PHP_5_1]$ php -r 'class R{private function
> __construct(){echo "R\n";}} class D extends R{static function
> f(){var_dump(new self);}} D::f();'
> make: `sapi/cli/php' is up to date.
> R
> object(D)#1 (0) {
> }
> [marcus@zaphod PHP_5_1]$ cd ../PHP_5_2
> [marcus@zaphod PHP_5_2]$ php -r 'class R{private function
> __construct(){echo "R\n";}} class D extends R{static function
> f(){var_dump(new self);}} D::f();'
> make: `sapi/cli/php' is up to date.
> 
> Fatal error: Call to private R::__construct() from context 'D' in
> Command line code on line 1
> 
> So yes, there is a bug with the inheritance rules in older versions.
> 
> > […]
> told me
> > […]
> 
> Fix the code by finding the correct way that works with both old and
> new
> versions.
> 
> Best regards,
>  Marcus

---

## #36618 — Stanislav Malyshev — 2008-03-27T17:47:33+00:00

URL: https://externals.io/message/36606#36618 · In reply to: #36606

Hi!

> i noticed that some changes was made that 100% break all apps that do such
> stuff:
> 
> class x extends y
> {
>     public static function foo()
>     {
>         new self();
>     }
> }
> 
> class y
> {
>     private function __construct()
>     {
>         echo 'y::__construct()' . PHP_EOL;
>     }
> }

I think that private ctor should mean "nobody but this class can create 
instances of this class". If somebody else is to create them, I'd say 
protected ctor is in place.
-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

## #36686 — Derick Rethans — 2008-03-30T15:30:47+00:00

URL: https://externals.io/message/36606#36686 · In reply to: #36613

> This means this "was maybe a bug, that i allread talked about" but its now
> changed so we should raise a notice about this. That will BREAK
> Many many apps out there.
> 
> For example, PHPUNIT, ZendFramework, ezComponents.

I've tested with eZ Components, but I do not see anything that breaks. 
Could you elaborate?

However, perhaps we should delay this change to PHP 5.3 - changes like 
this in mini versions are annoying.

Derick
-- 
Derick Rethans
http://derickrethans.nl | http://ezcomponents.org | http://xdebug.org

---

## #36687 — Sebastian Bergmann — 2008-03-30T16:55:25+00:00

URL: https://externals.io/message/36606#36687 · In reply to: #36613

Marco Kaiser schrieb:
> For example, PHPUNIT, ZendFramework, ezComponents.

  How exactly do you think PHPUnit breaks?

-- 
Sebastian Bergmann                          http://sebastian-bergmann.de/
GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69

---

## #36712 — Marcus Boerger — 2008-03-31T15:14:37+00:00

URL: https://externals.io/message/36606#36712 · In reply to: #36686

Hello Derick,

  it is a BUG FIX. Not fixing it means more people will turn it into a
feature and we will never be able to remove it. Becuase next time you
will say we cannot remove it in a minor version as by then you accidentally
rely on it yourself.

We made a mistake! Lets stand up and admit we did. Probably I was involved
in making that mistake, so sorry. Done.

marcus

Sunday, March 30, 2008, 5:30:47 PM, you wrote:

> 

> > […]

> I've tested with eZ Components, but I do not see anything that breaks. 
> Could you elaborate?

> However, perhaps we should delay this change to PHP 5.3 - changes like 
> this in mini versions are annoying.

> Derick
> -- 
> Derick Rethans
> http://derickrethans.nl | http://ezcomponents.org | http://xdebug.org




Best regards,
 Marcus

---

## #36722 — Pierre Joye — 2008-03-31T15:44:46+00:00

URL: https://externals.io/message/36606#36722 · In reply to: #36712

> Hello Derick,
>
>   it is a BUG FIX. Not fixing it means more people will turn it into a
>  feature and we will never be able to remove it. Becuase next time you
>  will say we cannot remove it in a minor version as by then you accidentally
>  rely on it yourself.
>
>  We made a mistake! Lets stand up and admit we did. Probably I was involved
>  in making that mistake, so sorry. Done.

We all understand that bugs (or design mistakes) have to be fixed at
some point. However, I'm not sure such fixes require yet again another
fatal error addition, especially not between two bug fixes only
releases. I may live (hardly) with a fatal error between 5.x and
5.x+1, on a case by case basis. And it is perfectly fine to do it in
6.x. I know we have been said that for months now but to explain our
position once again can't hurt.

Cheers and keep the good work,
-- 
Pierre
http://blog.thepimp.net | http://www.libgd.org

---

## #36730 — johannes@php.net — 2008-03-31T21:18:34+00:00

URL: https://externals.io/message/36606#36730 · In reply to: #36712

Marcus,


> Hello Derick,
> 
>   it is a BUG FIX. Not fixing it means more people will turn it into a
> feature and we will never be able to remove it. Becuase next time you
> will say we cannot remove it in a minor version as by then you accidentally
> rely on it yourself.
> 
> We made a mistake! Lets stand up and admit we did. Probably I was involved
> in making that mistake, so sorry. Done.

I have to agree with Derick here we shouldn't add a fatal error within a
bug fix release at such a place. People (hosters...) tend to update
versions without checking all incompatibilities - since you don't expect
them and they want to get security issues fixed.

Yes, the previous behavior was wrong! Yes we shouldn't encourage people
do do that.

I'd propose making it an Warning or something in 5.2 and fixing it in
5.3.

johannes

---

## #36735 — Pierre Joye — 2008-03-31T22:22:55+00:00

URL: https://externals.io/message/36606#36735 · In reply to: #36730

> Marcus,
>
>
>  
> > […]
>
>  I have to agree with Derick here we shouldn't add a fatal error within a
>  bug fix release at such a place. People (hosters...) tend to update
>  versions without checking all incompatibilities - since you don't expect
>  them and they want to get security issues fixed.
>
>  Yes, the previous behavior was wrong! Yes we shouldn't encourage people
>  do do that.
>
>  I'd propose making it an Warning or something in 5.2 and fixing it in
>  5.3.

 `E_DEPRECATED`  is more appropriate.

-- 
Pierre
http://blog.thepimp.net | http://www.libgd.org

---

## #36736 — Hannes Magnusson — 2008-03-31T22:25:59+00:00

URL: https://externals.io/message/36606#36736 · In reply to: #36735

> 
> > […]
>
>  `E_DEPRECATED`  is more appropriate.

In 5.2? 5.2 doesn't have `E_DEPRECATED` and this should be fixed in 5.3,
not issue a warning that it will be fixed in 5.4 or 6

-Hannes

---

## #36737 — Pierre Joye — 2008-03-31T22:35:26+00:00

URL: https://externals.io/message/36606#36737 · In reply to: #36736

On Tue, Apr 1, 2008 at 12:25 AM, Hannes Magnusson
<hannes.magnusson@gmail.com> wrote:
>
> 
> > […]
>
>  In 5.2? 5.2 doesn't have `E_DEPRECATED` 

Right, then a `E_NOTICE` will do it as well, but please no warning.

> and this should be fixed in 5.3, not issue a warning that it will be fixed in 5.4 or 6

I don't see a reason for a fatal error in this case.

But if we suddenly agree that fatal errors are common, then please do
it in 5.3 and add a notice only in 5.2.x. It should also be clearly
documented in the OO documentation section.

Cheers,
-- 
Pierre
http://blog.thepimp.net | http://www.libgd.org
