什么时候静态类变量是共享的?


When are static class variables shared?

我对Wordpress环境中PHP静态类变量的理解是,如果在同一个http请求中实例化了同一个类的2个或多个对象,那么它们的类静态变量将被共享。

不同的 http请求怎么办?类静态变量是否在 http请求之间共享 ?还是为每个http请求创建一个对象的全新副本?

不,它们不是共享的。对于每个请求,都将创建全新的对象。请记住,HTTP是无状态协议。这就是为什么很多人认为Singleton是反模式的(1)

基本上,如果你有下面的代码:

<?php
class MyClass {
    public function __construct() {
        // any action
    }
    public function anyMethod() {
        // any code
    }
}
$obj = new MyClass;

$obj是为每个请求从头创建的。实际上,这还不是全部。你的整个应用程序是从头"创建"的。


1)为什么Singleton被认为是反模式?

TL;DR: No。静态/全局状态在http请求之间不持久。


你需要理解类和对象之间的区别才能回答你的问题。

类是创建单个对象的模板。类本身是静态的,这意味着它具有全局作用域。一旦你声明了一个类,你就可以在当前进程中代码的任何地方执行new Class

对象是类的实例。它只能通过包含它的变量(指针)来访问。

静态关键字是什么意思?基本上,当您声明静态属性时,您为类声明了一个属性。正如我之前所说,一个类是唯一的和全局的,所以它的属性也将是唯一的和全局的。

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请求。

每次你的web服务器收到一个新的请求,它启动一个新的 PHP进程,将执行指定的脚本。因此,全局状态不会在http请求之间持久存在,因为每个请求都在自己的PHP进程中执行。