如何初始化静态变量

问题描述 投票:0回答:10

我有这个代码:

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 中出现意外的“(”,期望“)”

所以,我想我做错了什么......但是如果不是那样的话我该怎么做呢?如果我用常规字符串更改 mktime 内容,它就会起作用。所以我知道我可以做到有点那样..

有人指点一下吗?

php class static-members
10个回答
359
投票

PHP 无法解析初始值设定项中的非平凡表达式。

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

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

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

PHP 5.6 现在可以处理一些表达式了。

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

34
投票

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

示例:

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

23
投票

我宁愿简单地创建一个 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...
}

13
投票

我结合使用了 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() ]]
    }
}

但是更好的解决方案是取消静态方法并使用单例模式。然后你只需在构造函数中进行复杂的初始化即可。或者将其作为“服务”并使用依赖注入将其注入到任何需要它的类中。


10
投票

这太复杂了,无法在定义中设置。不过,您可以将定义设置为 null,然后在构造函数中检查它,如果它没有更改 - 设置它:

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

4
投票

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

/**
* @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();从任何地方。


4
投票

在 PHP 7.0.1 中,我能够定义这个:

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

然后像这样使用它:

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

3
投票

您不能在这部分代码中进行函数调用。 如果您创建一个 init() 类型的方法,该方法在任何其他代码执行之前执行,那么您将能够填充该变量。


0
投票

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

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

-1
投票

这里是一个代码示例,希望对您有所帮助。 请注意初始化函数如何仅被调用一次。

此外,如果您反转对

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
)
© www.soinside.com 2019 - 2024. All rights reserved.