最近看代码,发现有个代码写的有意思,在函数内用static修饰局部变量。当时心想,难道是跟global一样,扩大作用域?又看到同一个类里面,两个方法都用static修饰了同样的变量,我明白了,事情肯定没有我想象的这么简单,所以我写了下面的这个方法来测试下。
<?php
class MyTest
{
public static function func1($arg1)
{
static $result = [];
$p = serialize($arg1);
var_dump($p);
if (isset($result[$p])) {
return $result[$p];
}
$result[$p] = date('Y-m-d H:i:s') . " by func1 rand:".rand(0,100);
return $result[$p];
}
public static function func2($arg1)
{
static $result = [];
$p = serialize($arg1);
var_dump($p);
if (isset($result[$p])) {
return $result[$p];
}
$result[$p] = date('Y-m-d H:i:s') . " by func2 rand:".rand(0,100);
return $result[$p];
}
}
$arg = ['1' => '2'];
var_dump(MyTest::func1($arg));
var_dump(MyTest::func2($arg));
var_dump(MyTest::func1($arg));
var_dump(MyTest::func2($arg));
这个输出应该是如何呢?大家不妨想一想。同样的static $result 结果会相同吗?
好了我们一起来看输出。
string(18) "a:1:{i:1;s:1:"2";}"
string(36) "2020-04-28 03:30:04 by func1 rand:45"
string(18) "a:1:{i:1;s:1:"2";}"
string(36) "2020-04-28 03:30:04 by func2 rand:40"
string(18) "a:1:{i:1;s:1:"2";}"
string(36) "2020-04-28 03:30:04 by func1 rand:45"
string(18) "a:1:{i:1;s:1:"2";}"
string(36) "2020-04-28 03:30:04 by func2 rand:40"
从上面可以看出,static $result的作用域还是自己的函数内。但是在类实例化的生命周期内,当函数返回结果时,其生命周期并没有释放。
那么我们可以利用这个特性来缓存函数操作的结果,而又不需要定义类的成员变量。
