Using class constants and overriding in PHP
If I have a class structure with a value that can be true or false, this does not change, currently implemented as variables, it would be better to change them to constants, e.g .:
class Parent {
const BOOL_CONST = false;
...
}
class SomeChild extends Parent {
const BOOL_CONST = true;
...
}
Later I have an object that can be of any type in this class hierarchy, either parent or one of its children, and some of them, like "SomeChild", can overload true.
Is there a way to access the constant without knowing the class? In other words, I can do something like:
$object->BOOL_CONST
Or would it be better to leave these values as variables, even if they really shouldn't change?
UPDATE
I have reformulated my question above to better express what I was trying to ask.
source to share
PHP 5.3 now accepts an object as a class reference: is $this::BOOL_CONST
now accepted.
//
// http://php.net/manual/en/language.oop5.constants.php
//
// As of PHP 5.3.0, it possible to
// reference the class using a variable.
// The variable value can not be a keyword
// (e.g. self, parent and static).
//
// I renamed "Parent" class name to "constantes"
// because the classname "Parent" can be confused with "parent::" scope
class constantes
{
const test = false;
}
// I renamed "SomeChild" too, with no reason...
class OverloadConst extends constantes
{
const test = true;
public function waysToGetTheConstant()
{
var_dump(array('$this'=>$this::test)); // true, also usable outside the class
var_dump(array('self::'=>self::test)); // true, only usable inside the class
var_dump(array('parent::'=>parent::test)); // false, only usable inside the class
var_dump(array('static::'=>static::test)); // true, should be in class static methods, see http://php.net/manual/en/language.oop5.late-static-bindings.php
}
}
// Classic way: use the class name
var_dump(array('Using classname' => OverloadConst::test));
// PHP 5.3 way: use the object
$object = new OverloadConst();
var_dump(array('Using object' => $object::test));
$object->waysToGetTheConstant();
Note that you can override a class constant, but not an interface constant. If constantes
is an implementable interface, OverloadConsts
then you cannot override const test
(or BOOL_CONST
).
Sources
- Constants in PHP 5.3: http://php.net/manual/en/language.oop5.constants.php
- Late static bindings: http://php.net/manual/en/language.oop5.late-static-bindings.php
source to share
Is there a way to access the constant without knowing the class? In other words, I can do something like:
Yes, you need the following constructs to reference a constant:
- self :: NAME_OF_CONSTANT : provide a constant defined in this class; if i don't define it get it from my parent
- static :: NAME_OF_CONSTANT : give me a constant defined in this class ONLY; never look at a parent for him
- parent :: NAME_OF_CONSTANT : give me a constant defined in my parent class ONLY; never look yourself at it
By the way, you used the term "overloaded"; however, I believe you meant "overridden". Overloading has different meanings in object-oriented languages.
source to share
No, you cannot access constants from an object context, but you can use reflection to grab the $ object's class and then use :: to get BOOL_CONST. So:
$class = get_class($object);
$class::BOOL_CONST;
Ok, no, this is not technically a reflection. Also, I'm not 100% sure if $ class :: will resolve correctly. Use actual ReflectionClass if the above doesn't work.
source to share