【问题标题】:PHP static class member scopePHP 静态类成员范围
【发布时间】:2012-06-25 05:37:39
【问题描述】:

让我先说一下,我来自 Java 背景。

PHP 中静态类成员的范围是什么? 即:请求、会话、服务器生命周期等

我目前的理解是,一切都是请求,除非它卡在会话中。我在Language Guide 中没有找到任何可以反驳或确认的内容。

示例

class MyKlass {
    public static $K_PAGE_SIZE = 50;
    public static $K_WITH_SPRINKLES = true;
}

if (isset($_GET['NO_SPRINKLES'])) {
    MyKlass::$K_WITH_SPRINKLES = false;
}

var_dump(MyKlass::$K_WITH_SPRINKLES);

案例 1

如果我要访问包含此代码且查询行中没有任何内容的页面,我应该会看到

bool(true)

案例 2

如果我要访问带有此代码和查询行中的?NO_SPRINKLES=true 的页面,我应该会看到

bool(false)

案例 3

如果我访问查询行中带有?NO_SPRINKLES=true 的页面,然后访问没有它的页面,我应该总是看到 bool(true) 对吗?

案例 4

使用?NO_SPRINKLES=true 访问该页面后,其他访问该页面的人仍应看到 bool(true) 正确吗?

【问题讨论】:

  • 是的.. 这就是它应该工作的方式......当然,如果你这样做了?NO_SPRINKLES=,你也会得到错误,因为你正在测试密钥的存在,而不是值。
  • 创建这个写得很好的问题的时间本可以用于实际测试它;)
  • @Dvir Azulay,绝对正确,但我发帖的目的是双重的。一、文档与他人共享。二,看看是否有人指出文档中的某些内容或提供比“这个实验通过了我的测试,所以我假设它是真的”更详细的解释

标签: php oop scope static-members


【解决方案1】:

这不是关于 PHP,而是关于 HTTP 请求-响应周期。看,HTTP 被明确定义为无状态协议。这意味着每个新请求都会被处理,因为它之前没有任何内容(之后也没有任何内容,但这听起来太悲观了)。

是的,有几种机制可以减少这种“无状态”——cookie,它们存储在客户端;会话,它使用 cookie 或某些参数作为存储在服务器端的信息的键。但总的来说,您的理解是非常正确的:PHP 使用的每个实体的时间跨度(不存储在数据库/文件或会话中)只是一个 请求

【讨论】:

  • 嗯,这不仅仅是只是关于请求-响应周期,它还取决于部署应用程序的服务器/容器。例如,在 java 中,一旦访问了 ?NO_SPRINKLES=true 页面,在服务器实例重新启动之前访问该页面的每个人的结果将是 bool(false)
  • 看,HTTP 在设计上是无状态:如果你不相信我,可能this doc 更有说服力。 ) 再说一次,这并不意味着您不能在其基础上实现有状态系统,但是您必须将这些状态存储在某个地方。
  • 当然 HTTP 是无状态的,我不是这个意思。有些语言/环境中没有内存中的对象。例如,如果我在 WebLogic 环境中有一个类似的设置,我可以有一个名为 MyKlass 的静态类。无论请求是否到来,该对象都将保留在内存中。如果一个请求导致该对象发生更改,则更改后的对象将保留在内存中并由下一个请求访问。下一个请求也会看到更改。
  • @hidden_​​premise:是的,apache 确实保留了一个 PHP 进程池来加快处理速度,但理论上它们都是独立的,并且在收到请求时会“生成和销毁”;)
  • @hidden_​​premise 您的假设是正确的。 PHP 中没有应用程序内存。每个请求都会创建和销毁所有内容。甚至放入 Session 的对象也被序列化和反序列化,因此您在请求 A 中设置的静态成员永远不会与请求 B 中的相同。
【解决方案2】:

除非您使用会话,否则 PHP 不会保留任何信息。因此,当您加载页面时,会在代码开头创建一个变量,并在代码末尾发送时销毁。

类及其成员也是如此。您可以随意编辑它们,它会保留信息,但在脚本的最后,它会丢失。

【讨论】:

  • 谢谢大家! 来自 cmets 关于raina77ow 回答的更多好信息 “PHP 中没有应用程序内存。每个请求都会创建和销毁所有内容。即使放入 Session 的对象也被序列化和反序列化,因此是静态的您在请求 A 中设置的成员永远不会与请求 B 中的成员相同” -@Gordon。 AND “是的,apache 确实保留了一个 PHP 进程池来加快处理速度,但理论上它们都是独立的,并且在收到请求时会“生成和销毁”” - @Alex Belanger。
猜你喜欢
  • 2013-02-16
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 2016-01-09
  • 1970-01-01
  • 2016-11-27
  • 2018-10-05
  • 1970-01-01
相关资源
最近更新 更多