Edit report at https://bugs.php.net/bug.php?id=63976&edit=1
ID: 63976
User updated by: don at smugmug dot com
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:
'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.
Previous Comments:
------------------------------------------------------------------------
[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