How to initialize static variables

PhpClassStatic Members

Php Problem Overview


I have this code:

private static $dates = array(
  'start' => mktime( 0,  0,  0,  7, 30, 2009),  // Start date
  'end'   => mktime( 0,  0,  0,  8,  2, 2009),  // End date
  'close' => mktime(23, 59, 59,  7, 20, 2009),  // Date when registration closes
  'early' => mktime( 0,  0,  0,  3, 19, 2009),  // Date when early bird discount ends
);

Which gives me the following error:

>Parse error: syntax error, unexpected '(', expecting ')' in /home/user/Sites/site/registration/inc/registration.class.inc on line 19

So, I guess I am doing something wrong... but how can I do this if not like that? If I change the mktime stuff with regular strings, it works. So I know that I can do it sort of like that..

Anyone have some pointers?

Php Solutions


Solution 1 - Php

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();
}

Solution 2 - Php

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() }

Solution 3 - Php

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...
}

Solution 4 - Php

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.

Solution 5 - Php

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( /* .... */);
    }
}

Solution 6 - Php

You can't make function calls in this part of the code. If you make an init() type method that gets executed before any other code does then you will be able to populate the variable then.

Solution 7 - Php

best way is to create an accessor like this:

/**
* @var object $db : map to database connection.
*/
public static $db= null; 

/**
* db Function for initializing variable.   
* @return object
*/
public static function db(){
 if( !isset(static::$db) ){
  static::$db= new \Helpers\MySQL( array(
    "hostname"=> "localhost",
    "username"=> "root",
    "password"=> "password",
    "database"=> "db_name"
    )
  );
 }
 return static::$db;
}

then you can do static::db(); or self::db(); from anywhere.

Solution 8 - Php

In PHP 7.0.1, I was able to define this:

public static $kIdsByActions = array(
  MyClass1::kAction => 0,
  MyClass2::kAction => 1
);

And then use it like this:

MyClass::$kIdsByActions[$this->mAction];

Solution 9 - Php

Here is a hopefully helpful pointer, in a code example. Note how the initializer function is only called once.

Also, if you invert the calls to StaticClass::initializeStStateArr() and $st = new StaticClass() you'll get the same result.

$ cat static.php
<?php

class StaticClass {

  public static  $stStateArr = NULL;

  public function __construct() {
    if (!isset(self::$stStateArr)) {
      self::initializeStStateArr();
    }
  }

  public static function initializeStStateArr() {
    if (!isset(self::$stStateArr)) {
      self::$stStateArr = array('CA' => 'California', 'CO' => 'Colorado',);
      echo "In " . __FUNCTION__. "\n";
    }
  }

}

print "Starting...\n";
StaticClass::initializeStStateArr();
$st = new StaticClass();

print_r (StaticClass::$stStateArr);

Which yields :

$ php static.php
Starting...
In initializeStStateArr
Array
(
    [CA] => California
    [CO] => Colorado
)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSvishView Question on Stackoverflow
Solution 1 - PhpKornelView Answer on Stackoverflow
Solution 2 - PhpEmanuel LandeholmView Answer on Stackoverflow
Solution 3 - PhpdiggieView Answer on Stackoverflow
Solution 4 - PhpMambazoView Answer on Stackoverflow
Solution 5 - PhpAlister BulmanView Answer on Stackoverflow
Solution 6 - PhpalxpView Answer on Stackoverflow
Solution 7 - PhpespaciomoreView Answer on Stackoverflow
Solution 8 - PhpBuffaloView Answer on Stackoverflow
Solution 9 - PhpDavid LuhmanView Answer on Stackoverflow