我有这样的代码:

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

这给了我以下错误:

解析错误:语法错误,在/home/user/ sites /site/registration/inc/registration.class中出现意外的'(',期望')'。第19行

所以,我想我做错了什么…但如果不是那样,我怎么能这样做呢?如果我用常规字符串改变mktime,它就能工作。所以我知道我可以这样做。

有人有什么建议吗?


当前回答

如果你可以控制类加载,你可以从那里进行静态初始化。

例子:

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

在你的类装入器中,执行以下操作:

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

一个更重量级的解决方案是使用ReflectionClass接口:

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

在你的类装入器中,执行以下操作:

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

其他回答

在这部分代码中不能进行函数调用。如果你让init()类型的方法在其他代码执行之前执行,那么你就可以填充变量。

我结合了Tjeerd Visser和porneL的答案。

class Something
{
    private static $foo;

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

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

但是更好的解决方案是去掉静态方法,使用单例模式。然后在构造函数中进行复杂的初始化。或者让它成为一个“服务”,并使用DI将其注入到任何需要它的类中。

在我的例子中,我同时使用静态和非静态类属性,甚至可能在定义类之前让主程序代码引用类的静态部分。由于类的静态部分没有构造函数,只需添加一个手动构造函数来初始化任何需要非平凡计算的变量:

class A
   {
   static $a; // Initialized by Init()
   static function Init()
      {
      A::$a=nontrivial();
      {
   }
...
A::Init();    // Initialize static part of class
...
$obj=new A(); // Using initialized class as an object

如果你可以控制类加载,你可以从那里进行静态初始化。

例子:

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

在你的类装入器中,执行以下操作:

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

一个更重量级的解决方案是使用ReflectionClass接口:

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

在你的类装入器中,执行以下操作:

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

下面是一个代码示例,希望有帮助。注意初始化函数只被调用一次。

同样,如果反转对StaticClass::initializeStStateArr()和$st = new StaticClass()的调用,将得到相同的结果。

$ 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);

结果是:

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