php - 如何初始化静态变量
我有这个代码:
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内容,它就可以工作。 所以我知道我可以这样做..
有人有指点吗?
9个解决方案
322 votes
PHP无法解析初始值设定项中的非平凡表达式。
我更喜欢通过在定义类之后添加代码来解决这个问题:
class Foo {
static $bar;
}
Foo::$bar = array(…);
要么
class Foo {
private static $bar;
static function init()
{
self::$bar = array(…);
}
}
Foo::init();
PHP 5.6现在可以处理一些表达式。
Kornel answered 2019-03-12T14:07:57Z
32 votes
如果您可以控制类加载,则可以从那里进行静态初始化。
例:
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() }
Emanuel Landeholm answered 2019-03-12T14:08:46Z
23 votes
我没有找到让静态变量工作的方法,而是简单地创建一个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...
}
diggie answered 2019-03-12T14:09:29Z
11 votes
这太复杂了,无法在定义中设置。 您可以将定义设置为null,然后在构造函数中检查它,如果它还没有更改 - 设置它:
private static $dates = null;
public function __construct()
{
if (is_null(self::$dates)) { // OR if (!is_array(self::$date))
self::$dates = array( /* .... */);
}
}
Alister Bulman answered 2019-03-12T14:09:55Z
10 votes
我使用了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() ]]
}
}
但更好的解决方案是取消静态方法并使用Singleton模式。 然后你只需要在构造函数中进行复杂的初始化。 或者将其作为“服务”并使用DI将其注入任何需要它的类中。
Mambazo answered 2019-03-12T14:10:28Z
4 votes
您不能在代码的这一部分中进行函数调用。 如果你创建一个在任何其他代码之前执行的init()类型方法,那么你就可以填充变量了。
alxp answered 2019-03-12T14:10:56Z
3 votes
最好的方法是创建一个这样的访问器:
/**
* @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(); 或者自我:: db(); 从任何地方。
espaciomore answered 2019-03-12T14:11:28Z
2 votes
在PHP 7.0.1中,我能够定义:
public static $kIdsByActions = array(
MyClass1::kAction => 0,
MyClass2::kAction => 1
);
然后像这样使用它:
MyClass::$kIdsByActions[$this->mAction];
Buffalo answered 2019-03-12T14:11:58Z
0 votes
在代码示例中,这是一个非常有用的指针。 请注意初始化函数仅被调用一次。
此外,如果您将呼叫反转为StaticClass::initializeStStateArr()和$st = new StaticClass(),您将得到相同的结果。
$ cat static.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
)
David Luhman answered 2019-03-12T14:12:42Z