Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize static variables

PHP can't parse non-trivial expressions in initializers.

I prefer to work around this by adding code right after definition of the class:

class Foo {
  static $bar;
}
Foo::$bar = array(…);

or

class Foo {
  private static $bar;
  static function init()
  {
    self::$bar = array(…);
  }
}
Foo::init();

PHP 5.6 can handle some expressions now.

/* For Abstract classes */
abstract class Foo{
    private static function bar(){
        static $bar = null;
        if ($bar == null)
            bar = array(...);
        return $bar;
    }
    /* use where necessary */
    self::bar();
}

If you have control over class loading, you can do static initializing from there.

Example:

class MyClass { public static function static_init() { } }

in your class loader, do the following:

include($path . $klass . PHP_EXT);
if(method_exists($klass, 'static_init')) { $klass::staticInit() }

A more heavy weight solution would be to use an interface with ReflectionClass:

interface StaticInit { public static function staticInit() { } }
class MyClass implements StaticInit { public static function staticInit() { } }

in your class loader, do the following:

$rc = new ReflectionClass($klass);
if(in_array('StaticInit', $rc->getInterfaceNames())) { $klass::staticInit() }

Instead of finding a way to get static variables working, I prefer to simply create a getter function. Also helpful if you need arrays belonging to a specific class, and a lot simpler to implement.

class MyClass
{
   public static function getTypeList()
   {
       return array(
           "type_a"=>"Type A",
           "type_b"=>"Type B",
           //... etc.
       );
   }
}

Wherever you need the list, simply call the getter method. For example:

if (array_key_exists($type, MyClass::getTypeList()) {
     // do something important...
}

I use a combination of Tjeerd Visser's and porneL's answer.

class Something
{
    private static $foo;

    private static getFoo()
    {
        if ($foo === null)
            $foo = [[ complicated initializer ]]
        return $foo;
    }

    public static bar()
    {
        [[ do something with self::getFoo() ]]
    }
}

But an even better solution is to do away with the static methods and use the Singleton pattern. Then you just do the complicated initialization in the constructor. Or make it a "service" and use DI to inject it into any class that needs it.


That's too complex to set in the definition. You can set the definition to null though, and then in the constructor, check it, and if it has not been changed - set it:

private static $dates = null;
public function __construct()
{
    if (is_null(self::$dates)) {  // OR if (!is_array(self::$date))
         self::$dates = array( /* .... */);
    }
}