Question

If I have a class structure with a value that can either be true or false, that doesn't change, currently implemented as variables would it be better to change them to constants, such as:

class Parent {
    const BOOL_CONST = false;

    ...
}

class SomeChild extends Parent {
    const BOOL_CONST = true;

    ...
}

Later I have an object which may be of any type in that class hierarchy, either the parent or one of its children, and some of the children may, like 'SomeChild' have overloaded the value to be true.

Is there some way I can access the constant without knowing the class? In other words can I do something like:

$object->BOOL_CONST

Or would it be better to leave these values as variables, even though they really shouldn't change?

UPDATE

I've reworded my question above to better express what I was attempting to ask.

Was it helpful?

Solution

PHP 5.3 now accepts the object as the class reference: $this::BOOL_CONST is now accepted.

//
// http://php.net/manual/en/language.oop5.constants.php
//
// As of PHP 5.3.0, it's possible to
// reference the class using a variable.
// The variable's 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's 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 interface that OverloadConsts implements, then you can not override its const test (or BOOL_CONST).

Sources

OTHER TIPS

Is there some way I can access the constant without knowing the class? In other words can I do something like:

Yes, in order to reference a constant, you will want to use the following constructs:

  • self::NAME_OF_CONSTANT: give me 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 to my parent for it
  • parent::NAME_OF_CONSTANT: give me a constant defined in my parent class ONLY; never look to myself for it

BTW, you used the term "overloaded"; however, I believe you meant to say "overridden". Overloading has a different semantic meaning in object oriented languages.

Constant as access with the double colon ::

Parent::BOOL_CONST

SomeChild::BOOL_CONST

within the class
parent::BOOL_CONST  
self::BOOL_CONST

No, you can't access constants from an object context, but you could use reflection to grab the class of $object and then use :: to get BOOL_CONST. So:

$class = get_class($object);
$class::BOOL_CONST;

Okay, no, that's not technically reflection. Also, I'm not 100% sure if $class:: will resolve correctly. Use the actual ReflectionClass classes if the above doesn't work.

You cannot do $object->BOOL_CONST, since class constants have to be called statically (SomeChild::BOOLCONSTANT).

However, maybe you can try something like that: // edit: this works :)

$class = get_class($object);
$const = $class::BOOL_CONST;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top