php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51765 class constant has different setter behavior than global constant
Submitted: 2010-05-07 15:17 UTC Modified: 2010-09-03 20:53 UTC
From: colin at sheaff dot net Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: Irrelevant OS: Any
Private report: No CVE-ID: None
 [2010-05-07 15:17 UTC] colin at sheaff dot net
Description:
------------
Global constants can be set using string concatenation and other global constants. This is useful.

Class constants cannot be set using string concatenation or any functions, although they can be set to a global constant, or another class constant. The difference in setter behavior is confusing and limits utility of class constants.

Test script:
---------------
define( 'FOO', 'foo' );
define( 'BAR', FOO . 'bar' );
echo BAR . PHP_EOL;

class Foobar {
  const foo = 'foo';
  const bar = self::foo . 'bar';
}
echo Foobar::bar;

Expected result:
----------------
foobar
foobar

Actual result:
--------------
Parse error: syntax error, unexpected '.', expecting ',' or ';' on line 8

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-05-07 16:55 UTC] johannes@php.net
-Status: Open +Status: Bogus
 [2010-05-07 16:55 UTC] johannes@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

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 ...
 [2010-05-07 17:52 UTC] colin at sheaff dot net
And yet the following works:
define( 'FOO', 'foo' );
define( 'BAR', FOO . 'bar' );

class ThisWorks {
  const bar = BAR;
}

echo ThisWorks::bar;

If class constants are really compile time dependent, why is it ok to set one to 
a global const value which is only evaluated at run time?
 [2010-05-07 17:57 UTC] colin at sheaff dot net
In a more complicated example that shows how these dependencies are not clear-cut, 
the following also works:

define( 'BAR', ThisWorks::foo . 'bar' );

class ThisWorks {
  const foo = 'foo';
  const bar = BAR;
}

echo ThisWorks::bar;

this will output 'foobar' without an error.
 [2010-09-03 20:53 UTC] colin at sheaff dot net
In your response, you wrote - 
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.

However, why then does the code example from 2010-05-07 15:57 UTC work? This has 
a "compile time" class constant populated properly by a define() that is only 
evaluated at run time with a string concatenation. By your definition, this code 
should fail. Yet it doesn't, so I don't see how your explanation actually makes 
sense.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 28 20:01:29 2024 UTC