php 如何初始化静态变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/693691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 23:32:00  来源:igfitidea点击:

How to initialize static variables

phpclassstatic-members

提问by Svish

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

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

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 oflike that..

所以,我想我做错了什么......但如果不是那样我怎么能做到这一点?如果我使用常规字符串更改 mktime 内容,它会起作用。所以,我知道我能做到这一点的那种像..

Anyone have some pointers?

任何人都有一些指示?

回答by Kornel

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

PHP 无法解析初始化程序中的非平凡表达式。

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.6can handle some expressions now.

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

回答by Emanuel Landeholm

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:

更重的解决方案是使用带有 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() }

回答by diggie

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.

与其寻找让静态变量工作的方法,我更喜欢简单地创建一个 getter 函数。如果您需要属于特定类的数组,并且实现起来要简单得多,这也很有帮助。

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:

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

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

回答by Mambazo

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

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

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.

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

回答by Alister Bulman

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:

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

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

回答by alxp

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.

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

回答by Buffalo

In PHP 7.0.1, I was able to define this:

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

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

And then use it like this:

然后像这样使用它:

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

回答by espaciomore

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.

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

回答by David Luhman

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.

此外,如果您将调用反转为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);

Which yields :

产生:

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