如何初始化静态variables

我有这个代码:

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

这给了我以下错误:

在第19行的/home/user/Sites/site/registration/inc/registration.class.inc中parsing错误:语法错误,意外的'(',期待')'

所以,我想我做错了什么…但我怎么能这样做,如果不是这样的? 如果我用常规string更改mktime的东西,它的工作原理。 所以我知道我可以这样做。

任何人都有一些指针?

PHP不能在初始化器中分析不重要的expression式。

我更喜欢通过在类的定义之后添加代码来解决这个问题:

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

要么

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

现在PHP 5.6可以处理一些expression式。

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

例:

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

在你的类加载器中,执行以下操作:

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

更重的解决scheme是使用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() } 

而不是寻找一种方法来获得静态variables的工作,我更喜欢简单地创build一个getter函数。 如果您需要属于特定类的数组,并且实现起来更简单,那也很有帮助。

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

无论您需要列表,只需调用getter方法即可。 例如:

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

这个定义太复杂了。 您可以将该定义设置为null,然后在构造函数中检查它,如果没有更改 – 将其设置为:

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

我使用了Tjeerd Visser's和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() ]] } } 

但更好的解决scheme是取消静态方法并使用Singleton模式。 那么你只需要在构造函数中进行复杂的初始化。 或者把它变成一个“服务”,并使用DI将其注入到任何需要它的类中。

你不能在这部分代码中进行函数调用。 如果你创build一个init()types的方法在任何其他代码之前被执行,那么你将能够填充这个variables。

最好的方法是创build一个这样的访问器:

 /** * @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; } 

那么你可以做static :: db(); 或self :: db(); 从任何地方。

在PHP 7.0.1中,我可以定义这个:

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

然后像这样使用它:

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

在代码示例中,这是一个很有帮助的指针。 注意初始化函数只被调用一次。

另外,如果你调用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 )