【发布时间】:2015-10-14 19:35:36
【问题描述】:
我对 Wordpress 环境中 PHP 静态类变量的理解是,如果同一类的 2 个或多个对象在同一个 http 请求中实例化,那么它们的类静态变量将被共享。
不同的 http 请求呢?类静态变量是否曾经在 http 请求之间共享?还是为每个 http 请求创建一个全新的对象副本?
【问题讨论】:
我对 Wordpress 环境中 PHP 静态类变量的理解是,如果同一类的 2 个或多个对象在同一个 http 请求中实例化,那么它们的类静态变量将被共享。
不同的 http 请求呢?类静态变量是否曾经在 http 请求之间共享?还是为每个 http 请求创建一个全新的对象副本?
【问题讨论】:
不,它们不共享。在每个请求上,都会创建全新的对象。请记住,HTTP 是无状态协议。这就是为什么很多人认为 Singleton 是反模式的原因(1)。
所以,基本上如果你有以下代码:
<?php
class MyClass {
public function __construct() {
// any action
}
public function anyMethod() {
// any code
}
}
$obj = new MyClass;
$obj 是针对每个请求从头开始创建的。实际上,这还不是全部。您的整个应用程序都是从头开始“创建”的。
【讨论】:
static 属性,而不是类实例化或单例。
static 属性也是如此,因为它们是类的一部分,对吧?
TL;DR:否。静态/全局状态不会在 http 请求之间持续存在。
您需要了解类和对象之间的区别才能回答您的问题。
类是创建单个对象的模板。类本身是静态的,这意味着它具有全局范围。一旦你声明了一个类,你就可以在当前进程的代码中的任何地方执行new Class。
对象是类的一个实例。它只能通过包含它的变量(指针)来访问。
现在 static 关键字是什么意思?基本上,当您声明一个静态属性时,您就为该类声明了一个属性。正如我之前所说,一个类是唯一的和全局的,所以它的属性也将是唯一的和全局的。
class Exemple
{
public static $foo = 42;
}
echo Exemple::$foo; // 42
$object = new Exemple;
$object2 = new Exemple;
echo $object::$foo; // 42
echo $object2::$foo; // 42
Exemple::$foo = 1;
echo Exemple::$foo; // 1
echo $object::$foo; // 1
echo $object2::$foo; // 1
另一方面,当您声明一个对象属性时,它只能通过一个对象访问,并且它包含的值将特定于该对象。
class Exemple2
{
public $bar;
}
$object = new Exemple2;
$object2 = new Exemple2;
$object->bar = 42;
echo $object->bar; // 42
echo $object2->bar; // null
既然我们已经阐明了静态的东西,我们可以谈谈 http 请求。
每次您的网络服务器收到新请求时,它都会启动一个新 PHP 进程,该进程将执行指定的脚本。因此,全局状态不会在 http 请求之间持续存在,因为每个请求都在自己的 PHP 进程中执行。
【讨论】: