HomeSectionsAboutMerch
« Standardise core libraryStrict mode and internal engine callbacks »

Static class initialization

General idea

Some languages allow you to define some code that is run when a class is loaded for the first time.

public class Demo
{
    static double percentage;
    static int rank;
    static
    {
        percentage = 44.6;
        rank = 12;
        System.out.println("STATIC BLOCK");
    }
    public static void main(String args[])
    {
        Demo st = new Demo();
        System.out.println("MAIN METHOD");
        System.out.println("RANK: " + rank);
    }
}

People who are used to this style of code miss having it in PHP.

Hurdles to overcome

Easier in static linked languages

TODO - link to explanation of PHP's circular class dependency problem

Quite magic

The behaviour of static class initialization is quite magic. Johannes Schlüter put it quite clearly:

'In my opinion this makes the language way more complex as there are more places which "suddenly" execute code but solves a small problem compared to that. (Which actually is an issue many people would suggest to avoid completely instead of ennobling this with a language feature.)

Why am I saying it makes the language more complex? - Your proposal seems to miss mentioning when exactly the method is executed. what is the output of

a.php:
<?php
echo 'A: '.__FILE__.':'.__LINE__."\n";
class A {
    static function __static() {
      echo __CLASS__.'::'.__METHOD__."\n";
    }
}
echo 'B: '.__FILE__.':'.__LINE__."\n";
class B {
    static function __static() {
      echo __CLASS__.'::'.__METHOD__."\n";
    }
}
echo 'C: '.__FILE__.':'.__LINE__."\n";
?>

b.php:
<?php
echo 'D: '.__FILE__.':'.__LINE__."\n";

C::$foo = 23;
echo 'E: '.__FILE__.':'.__LINE__."\n";

include 'a.php';
echo 'F: '.__FILE__.':'.__LINE__."\n";


class C {
    static $foo = 0;
    static function __static() {
      echo __CLASS__.'::'.__METHOD__."\n";
    }
}

echo 'G: '.__FILE__.':'.__LINE__."\n";

class D extends B {
    static function __static() {
      echo __CLASS__.'::'.__METHOD__."\n";
    }
}

echo 'H: '.__FILE__.':'.__LINE__."\n";
?>

Mind that in b.php we make use of class C above the declaration, which we can do as C is a simple class and can be bound early during compilation. Class D however can only be bound during run-time, after including a.php, which happens after C was already used.'

It's already possible without engine support

class MyClass {
    public static DateTimeImmutable $startup;
    public function horribleInitializationPractices() {
        self::$startup = new DateTimeImmutable();
    }
}

MyClass::horribleInitializationPractices();

It's quite hard to make an argument for something to be added to the engine, when it's already possible in userland.

Forecast

Quite unlikely to happen, unless someone can find a strong justification for adding it to the language.

I would actually like it to be added, as static class initialization can be a useful paradigm for programming. But it's hard to imagine how it would work in PHP, where the whole application isn't completely compiled before being run.

Notes

Previous static class constructor RFC