On Wed, Feb 19, 2020 at 12:58 PM tyson andre <tysonandre...@hotmail.com>
wrote:

> Hi internals,
>
> > I've created a straw poll at
> https://wiki.php.net/rfc/calls_in_constant_expressions_poll , to measure
> interest in allowing calls in different types of constant expressions.
> > If there aren't any problems with the poll structure or rules preventing
> creating a poll, I was going to add it to the rfc index page and move it to
> voting.
>
> This straw poll has been moved to voting and added to the rfc index page.
> The poll will be closed on March 4th.
>

The original motivation was, IIRC, to initialize class constants with an
expression. Following KISS, I feel we should constrain our efforts to that
scope, and that's how I voted: "Yes" on class constants and static members,
"No" on everything else.

As for implementation, we must manage the complexity. I'm a hard "No" on
restricting use to an arbitrary, variable list of blessed functions. It's a
dev UX nightmare to include a bevy of array_* functions but no str*
functions.

Consequently, the only way to safely initialize class constants and static
members is at run-time, and I can only think of one way to do it. Apologies
if this has already been suggested: taking a cue from C#, a static class
constructor ([1]) would allow us to have expression-initialized constants
and static members.

<?php
class Config {
    public const URL = null; // compile time initialization
    protected static $mtime = null; // compile time initialization
    private static function __constructStatic() {
        $env = json_decode(file_get_contents('config.json'));
        self::URL = $env->url;
        self::$mtime = filemtime('config.json');
   }
   public function reload() {
       if (self::$mtime < filemtime('config.json'))
           self::__constructStatic();
       }
   }
}

echo Config::URL; // assert: runtime has already called _constructStatic
$config = new Config; // assert: __constructStatic called only once by
runtime
$config->reload(); // instance may call its own static constructor
?>

Trying to do the same for global constants, static variables, or function
default parameters resists a similar initialization mechanism because we
don't have defined common entry point analogues. If we had a main(), or if
we had framed @before decorators, we could do something similar, but we
don't -- so I feel we should leave these off the table.

Thank you, Tyson, for taking the time to progress this feature.

[1]:
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors

Reply via email to