> The problem with using constants is that the value is still hardcoded
> and if we later want to change to pulling the data from a config file 
> we have to change all the code that uses those constants. 

It's possible to work around this by using a unique constant name
and define('unique_name', $dynamicExpression)
(and const MY_CLASS_CONST = \unique_name;)

Maybe php could add something along these lines:

local const X = sprintf('In %s', $dynamicValue);
// Not supported in functions or loops.
// Translates internally to:
// if (defined('some_globally_unique_constant123af') || 
//     !define('some_globally_unique_constant123af', X)) { throw ...; }
// use some_globally_unique_constant123af as X;
class MyClass {
    const PUBLIC = X;
}

- php still needs to prevent recursion such as 
  `const A = count(B); const B = array_fill(1, A, 'value');`,
  which is why the simplest approach would be one that eagerly evaluates 
dynamic expressions.
  That's probably not the only way - maybe it could track all of the constants 
that
  are in the process of being defined and cause an uncatchable fatal error if 
there was recursion.
- Right now, reading the value of a class constant can already emit notices or 
throw an Error (undeclared constants)
  the first time it gets evaluated
- Any approach should throw for results that contain cycles, objects, or 
references,
  the same way define() warns.

The below ugly proof of concept shows that the php runtime can in a sense
defer evaluation of dynamic class constants to runtime (not recursively)
(assume errstr/errfile control what constant gets loaded).
This POC should not be used anywhere.

<?php
set_error_handler(function ($errno, $errstr) {
    echo "Ignoring $errno: $errstr\n";
    define(
        'SOME_GLOBALLY_UNIQUE_CONSTANT',
        sprintf('Hello, %s', $GLOBALS['globalVar'])
    );
});
class MyTest {
    const KEY = 'myKey';
    const FOO = [
        self::KEY => [[][0], SOME_GLOBALLY_UNIQUE_CONSTANT][1],
    ];
}
$globalVar = 'world';
echo "Fetching MyTest::FOO\n";
var_dump(MyTest::FOO);
/*
Output:
Fetching MyTest::FOO
Ignoring 8: Undefined offset: 0
array(1) {
  ["myKey"]=>
  string(12) "Hello, world"
}
 */

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to