3

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.

AntonChanning
  • 509
  • 2
  • 13
  • 37
  • possible duplicate of [Can I get CONST's defined on a PHP class?](http://stackoverflow.com/questions/956401/can-i-get-consts-defined-on-a-php-class) – Juicy Scripter Mar 30 '12 at 15:12
  • @JuicyScripter Don't see the similarity myself? I guess my question was more related to needing to obtain a value at object level that shouldn't change, but not knowing the classname. Currently these are implemented as variables but some part of me felt they should be constants. But it looks like doing it that way would break a lot of things. – AntonChanning Mar 30 '12 at 15:34

5 Answers5

7

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.

Wil Moore III
  • 6,968
  • 3
  • 36
  • 49
  • 1
    Thanks. You are right about my confising the terms 'overloading' and 'overriding'. I'll edit the question to use the correct term. – AntonChanning Apr 02 '12 at 11:02
2

Constant as access with the double colon ::

Parent::BOOL_CONST

SomeChild::BOOL_CONST

within the class
parent::BOOL_CONST  
self::BOOL_CONST
Yada
  • 30,349
  • 24
  • 103
  • 144
1

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

nobody
  • 19,814
  • 17
  • 56
  • 77
Xenos
  • 3,351
  • 2
  • 27
  • 50
1

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.

Matthemattics
  • 9,577
  • 1
  • 21
  • 18
  • +1 Although I suspect using the ReflectionClass might be overkill for my purposes. I'd probably be better off keeping the values as variables rather than tidying them into constants just because they shouldn't change. – AntonChanning Mar 30 '12 at 15:26
  • I agree; it's usually better to favor speed over cleanliness (I often do), and ReflectionClass is one slow behemoth. – Matthemattics Mar 30 '12 at 17:28
1

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;
haltabush
  • 4,508
  • 2
  • 24
  • 41