Edit report at https://bugs.php.net/bug.php?id=63976&edit=1

 ID:                 63976
 Patch added by:     m...@php.net
 Reported by:        don at smugmug dot com
 Summary:            Parent class incorrectly using child constant in
                     class property
 Status:             Open
 Type:               Bug
 Package:            Class/Object related
 Operating System:   Ubuntu 12.04
 PHP Version:        5.4.10
 Block user comment: N
 Private report:     N

 New Comment:

The following patch has been added/updated:

Patch Name: update_class_constants
Revision:   1360863036
URL:        
https://bugs.php.net/patch-display.php?bug=63976&patch=update_class_constants&revision=1360863036


Previous Comments:
------------------------------------------------------------------------
[2013-01-12 03:53:33] don at smugmug dot com

'Have a preference' should have said 'I have a preference'.  Certainly not 
intending for PHP to add some new INI option or something to change how 
static:: 
and self:: behave. :)

Also, have confirmed this on 5.4.4 and CentOS in addition to Ubuntu and 5.4.10, 
both with and without extensions like APC loaded.

------------------------------------------------------------------------
[2013-01-12 03:51:21] don at smugmug dot com

Description:
------------
Class properties that rely on potentially inherited class constants have 
unpredictable behavior.

Since PHP doesn't support Child class properties referencing static values like 
static::CONST, the meaning of self::CONST is ambiguous. One of two things 
should 
happen:

1. It should use the value defined in the actual class in question (like self:: 
is used throughout the rest of PHP).

2. It should treat self:: in this case, since it's compile-time and not late 
static binding, like static:: and walk the inheritance tree, delivering the 
result for the Child class.

Option #1 seems the most sane, but PHP often behaves like it intends #2 to 
work. 
But not always...

In the provided examples, 'brokenA.php' behaves like #1, above, while 
'brokenB.php' and 'brokenC.php' behave like #2. The only thing that's changed 
is 
the order in which the classes are require()'d.

In a complex script, with autoloaders, class instantiation order isn't 
predictable, of course, resulting in unpredictable results.

Test script:
---------------
Example code: https://github.com/onethumb/php-parent-child-constant-bug

Expected result:
----------------
Consistent results for Baz->table.  Either 'foo' or 'baz' 100% of the time, 
rather 
than mixed up depending on require() order.

Have a preference for adding static::CONST to PHP and making self::CONST behave 
like self:: does in the rest of the language (resulting in Baz->table == 'baz' 
in 
the examples if we used static::CONST), but if that's not preferable for some 
reason, self::CONST should probably behave like self:: everywhere else 
(resulting 
in Baz->table == 'foo' in the examples).

Actual result:
--------------
brokenA.php:
Bar Object
(
    [table] => bar
)
Baz Object
(
    [table] => foo
)

brokenB.php:
Bar Object
(
    [table] => bar
)
Baz Object
(
    [table] => baz
)

brokenC.php:
Baz Object
(
    [table] => baz
)
Bar Object
(
    [table] => bar
)
Baz Object
(
    [table] => baz
)


------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=63976&edit=1

Reply via email to