> 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