1

I am using Reflection against the following class:

class Constant {
    const CONSTANT = 3;
    public $test1 = 'CONSTANT';
    public $test2 = CONSTANT;
}

When using ReflectionClass::getDefaultProperties(); I get the following notice:

PHP Notice: Use of undefined constant CONSTANT - assumed 'CONSTANT'

on this line of code:

$defaultValues = $reflectionClass->getDefaultProperties();

First, I wonder why I get the notice here (I mean, I can't anticipate/avoid the notice even though the code is 100% correct)?

And second, when using var_export($defaultValues[3]), it outputs 'CONSTANT' which is normal because it has been casted to string.

So, how can I output CONSTANT instead of 'CONSTANT' for $test2 and still output a quote-delimited string for $test1?

Edit: I get CONSTANT for both cases ($test1 and $test2) but because of that I can't differentiate between them. I want to be able to know: that is a string, or that is the name of a constant.

Matthieu Napoli
  • 48,448
  • 45
  • 173
  • 261
  • Do you want `3` as output for `$defaultValues[3]`? – powtac Feb 29 '12 at 15:45
  • no I want `CONSTANT` as output for `$defaultValues[3];`. Right now I get `'CONSTANT'` (and there is no way for me to know if it's a constant being casted to string or just a normal string). – Matthieu Napoli Feb 29 '12 at 19:11
  • You want to get rid of the `'` around CONSTANT? – powtac Feb 29 '12 at 19:15
  • Sorry, my mistake: I get `CONSTANT` for both cases (`$test1` and `$test2`) but because of that I can't differentiate between them. I want to be able to know: that is a string, or that is the name of a constant. – Matthieu Napoli Feb 29 '12 at 19:28

2 Answers2

2

why I get the notice here?

because you mean self::CONSTANT but tried to use global CONSTANT, e.g. your code assumes

const CONSTANT = 3;              // global constant

class Constant {
    const CONSTANT = 3;          // class constant
    public $test1 = 'CONSTANT';
    public $test2 = CONSTANT;    // refers to global constant
}

but you wanted to do this:

class Constant {
    const CONSTANT = 3;
    public $test1 = 'CONSTANT';
    public $test2 = self::CONSTANT; // self indicated class scope
}

With the latter, this

$reflectionClass = new ReflectionClass('Constant');
var_dump( $reflectionClass->getDefaultProperties() );

will give

array(2) {
  ["test1"]=>
  string(8) "CONSTANT"
  ["test2"]=>
  int(3)
}

Is there a way to get ["test2"] => self::CONSTANT via Reflection? No. The Reflection API will evaluate the constant. If you want self::CONSTANT you'd have to try some of the 3rd party static reflection APIs.

And obviously, if you want 'CONSTANT', write "'CONSTANT'".

Regarding EDIT:

I get CONSTANT for both cases ($test1 and $test2) but because of that I can't differentiate between them. I want to be able to know: that is a string, or that is the name of a constant.

$foo = CONSTANT means assign the constant value to the foo property. It does not mean assign the constant itself. By assigning the value to a property, it no longer is a constant value. It's mutable. The "name of a constant" is represented as a string. You can use ReflectionClass::hasConstant to check whether that string happens to also be the name of a defined constant in the class or use defined for global constants.

Gordon
  • 312,688
  • 75
  • 539
  • 559
  • It seems to me more of a PHP bug + lack of feature (yeah that's easy to say that): the PHP method `ReflectionClass::getDefaultProperties()` raises a notice that I have no way to anticipate (the code of the class being reflected is 100% correct), and it provides me no way to differenciate between a constant and a string value. What is your opinion about that? – Matthieu Napoli Feb 29 '12 at 19:25
  • (btw I know that Reflection is a very young set of classes, even the documentation is ... young) – Matthieu Napoli Feb 29 '12 at 19:26
  • @Matthieu it's a bug in your code, not in the Reflection API. [If you use an undefined constant, PHP assumes that you mean the name of the constant itself. And it will raise a Notice. That's well documented](http://php.net/manual/en/language.constants.syntax.php). As for the Reflection docs being "young", I honestly dont see what you would need more in terms of docs for that when the method names are so obvious. – Gordon Feb 29 '12 at 19:46
  • of course I know what this notice is... Fact is that **I don't use** an undefined constant, it's PHP that uses it (through `ReflectionClass::getDefaultProperties()`). Did you read what I wrote? As for the documentation, it would be useful, for example knowing wether you get the methods of the class with or without the parent class' methods (inherited methods). That's the first example that comes to my mind. – Matthieu Napoli Feb 29 '12 at 21:21
  • @Matthieu `getDefaultProperties()` will return the property names **and values**. It says so in the Manual. To give you the *value* of `$test2`, PHP has to evaluate `CONSTANT`. There is no other way to represent a constant at runtime. So you *are* really asking PHP to use/eval the constant. As for which methods getMethods() returns: why should it return an incomplete class? If you have need for excluding the inherited methods, use this [this FilterIterator](https://github.com/gooh/InterfaceDistiller/blob/master/src/Filters/NoInheritedMethodsIterator.php) – Gordon Feb 29 '12 at 22:43
  • `you'd have to try some of the 3rd party static reflection APIs` Can you give me the names of some of them? I think that's what best suit my needs indeed – Matthieu Napoli Mar 01 '12 at 11:08
  • 1
    @Matthieu try the three given in http://stackoverflow.com/questions/9152700/are-there-any-good-php-libraries-that-can-convert-html-php-documents-into-object/9153852#9153852 – Gordon Mar 01 '12 at 11:19
1

Since you use CONSTANT for the value of $test2 and do not define it before it will throw the "undefined constant" error. Do you want to use the class constant CONSTANT as value for the public $test2? Then use public $test2 = self::CONSTANT. Otherwise define CONSTANT as constant before the class.

Please note that PHP casts all unknown constants as strings with the value of the name of the unknown constant.

powtac
  • 40,542
  • 28
  • 115
  • 170