PHP 函数中的静态变量是否跨实例全局?
如果我的代码使用 static
变量进行缓存,如下所示:
class BossParty
{
// ...
public function getTemplate()
{
static $template;
if ($template == null)
{
$template = BossTemplate::get($this->templateID);
}
return $template;
}
// ...
}
$template
会在 BossParty
的不同实例中持续存在吗?我尝试检查 php.net,但我所能找到的只是有关静态类变量的信息。
If I have code which uses a static
variable for caching purposes like this:
class BossParty
{
// ...
public function getTemplate()
{
static $template;
if ($template == null)
{
$template = BossTemplate::get($this->templateID);
}
return $template;
}
// ...
}
Will $template
persist across different instances of BossParty
? I've tried checking php.net, but all I can find is info about static class variables.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,静态变量将在类的实例中持续存在。
示例:
请注意,这对于后代类也是如此。如果我们有一个扩展了
Test
的类Child
,调用parent::__construct
(无论是显式还是隐式)将使用相同的值>$foo
.Yes, the static variable will persist across instances of the class.
Example:
Note that this is true for descendant classes too. If we had a class
Child
that extendedTest
, callingparent::__construct
(whether explicitly or implicitly) will use the same value of$foo
.@lonesomeday,这似乎大部分是正确的。然而,特别是与您有关继承的后续评论相关,函数内静态变量作用域的行为似乎更复杂。我的所有示例都使用 PHP 5.3.16。
摘要:
static
关键字在用于确定实例函数内的变量范围时,其行为似乎会根据继承和函数调用堆栈中的位置而有所不同。这里有几个例子。
首先,这与您最初的示例类似:在类的 __construct() 方法中实例化静态变量,创建该类的两个实例,然后查看该变量的行为方式。
到目前为止,没有什么意外。该变量被实例化一次(到 0),然后随着每个单独的实例而递增。
如果将类
A
扩展为B
,并实例化其中一个类(其他所有内容保持不变),您会得到相同的行为:再一次,没有什么意外。让我们回到第一个例子并稍微调整一下。首先,我们将静态变量实例化/增量调用移至成员方法。请注意,我已为此删除了类
B
:仍然是相同的输出。
但是,当您将
A
扩展为B
并保留相同的结构时:请注意输出:在所有其他情况下,
$o2->i
变成了 2,除了这个。因此,如果我们扩展
A
并将静态实例化移动到实例方法,我们现在似乎为$i 变量,而在所有其他情况下,实例共享该静态变量的作用域。
更令人困惑,请考虑这个例子;它与前一个相同,但在这种情况下,类
B
获得自己的setI()
实现,它只是屈服于其父类的实现:如您所见,
$o2->i
现在重新设置为 2,这就是我们几乎在所有地方都得到的值(除了示例#4),这对我来说似乎非常违反直觉。我希望不同的实例都有自己的变量作用域,或者所有实例(包括扩展类的实例)共享相同的作用域。
我无法判断这是否是 PHP 中的错误,或者是否是预期的行为。 有关静态变量作用域的 PHP 文档 说:
他们没有详细说明如何在对象实例的上下文中定义“函数作用域”,因此我不确定示例#4 中的边缘情况是否是预期的。
@lonesomeday, that seems to be mostly correct. However, in particular related to your followup comment regarding inheritance, the behavior of static variable scope inside functions seems to be more complex. I'm using PHP 5.3.16 for all my examples.
The summary: the behavior of the
static
keyword when used to scope a variable within an instance function seems to vary based both on inheritance and where in the function call stack you are.Here are a few examples.
First, this is similar to your initial example: instantiate a static variable within the
__construct()
method of a class, create two instances of that class, and see how that variable behaves.So far, no surprises. The variable is instantiated once (to 0) and then incremented with each separate instance.
If you extend class
A
asB
, and instantiate one of each (leaving everything else the same), you get the same behavior:Once again, no surprises. Let's go back to the first example and tweak it a bit. First we move the static variable instantiation/increment call to a member method. Note that I've removed class
B
for this one:Still the same output.
However, when you extend
A
asB
, and leave the same structure in place:Note the output: in all other cases,
$o2->i
became 2, except for this one.So it seems that if we extend
A
and move the static instantiation to an instance method, we now seem to have introduced a new scope for the$i
variable, whereas in all other cases the instances have shared a scope for that static variable.Even more confusing, consider this example; it's identical to the previous one, but in this case, class
B
gets its own implementation ofsetI()
, which simply yields to its parent class's implementation:As you can see,
$o2->i
is now back to being set to 2, which is what we got nearly everywhere (except Example #4)This, to me, seems very counterintuitive. I would expect that either different instances get their own scopes for that variable, or all instances (including instances of extended classes) share the same scope.
I can't tell if this is a bug in PHP, or if it's expected behavior. The PHP docs on static variable scope say:
They don't go into detail as to how 'function scope' is defined in the context of object instances, so I'm not sure if the edge case in Example #4 is expected or not.
是的,它也记录在文档中,但它位于 变量 部分下范围而不是静态关键字,这可能是你没有找到它的原因。
Yes it will, it's also documented in the docs, but it's under the section Variables Scope instead of the Static Keyword, which might be the reason you didn't find it.