views:

198

answers:

4

I know that you can create global constants in terms of each other using string concatenation:

define('FOO', 'foo');
define('BAR', FOO.'bar');  
echo BAR;

will print 'foobar'.

However, I'm getting an error trying to do the same using class constants.

class foobar {
  const foo = 'foo';
  const foo2 = self::foo;
  const bar = self::foo.'bar';
}

foo2 is defined without issue, but declaring const bar will error out

Parse error: syntax error, unexpected '.', expecting ',' or ';'

I've also tried using functions like sprintf() but it doesn't like the left paren any more than the string concatenator '.'.

So is there any way to create class constants in terms of each other in anything more than a trivial set case like foo2?

+1  A: 

no.

(I don't think there is)

Bingy
+2  A: 

Always fall back to the trusty manual for stuff like this.

Regarding constants:

The value must be a constant expression, not (for example) a variable, a property, a result of a mathematical operation, or a function call.

So... "no" would be the answer :D

Peter Bailey
A: 

For class constants, you can't assign anything other than a constant expression. Quoting the PHP manual:

"The value must be a constant expression, not (for example) a variable, a property, a result of a mathematical operation, or a function call. "

Dumb Guy
A: 

The only way is to define() an expression and then use that constant in the class

define('foobar', 'foo' . 'bar');

class Foo
{
    const blah = foobar;
}

echo Foo::blah;

Another option is to go to bugs.php.net and kindly ask them to fix this.

stereofrog
I don't understand the rationale for different setter behavior between global constants and class constants. I think I will visit bugs.php.net shortly :)But for the short-term, I'll probably just move the constants out of the class and then copy them into the class. So kludgy!
selfsimilar
bug.php.net basically told me they wouldn't fix it."This is a limitation in the implementation. For the class constant we need a constant value at compile time and can't evaluate expressions. define() is a regular function, evaluated at run time and can therefore contain any value of any form.changing this would mean to add an execution phase in the compiler ..."Which is actually BS, as the following code works:define( 'BAR', ThisWorks::foo . 'bar' );class ThisWorks { const foo = 'foo'; const bar = BAR;}echo ThisWorks::bar;this will output 'foobar' without an error.
selfsimilar