=== Base.php ===
<?php
class Base
{
public static function e()
{
static $number = 0;
$number++;
var_dump($number);
}
}
=== A.php ===
<?php
class A extends Base {}
=== B.php ===
<?php
class B extends Base {}
=== test.php ===
function __autoload($classname)
{
require_once("{$classname}.php");
}
Base::e();
A::e();
B::e();
php test.php, результат:
int(1)
int(2)
int(2)
Почему не результат 1,1,1?
Пытаться
require "Base.php";
Base::e();
require "A.php";
A::e();
против
require "Base.php";
require "A.php";
Base::e();
A::e();
Бывший даст int(1) int(2)
в то время как последний дает int(1) int(1)
,
Когда класс связан, static
переменное содержимое копируется именно в тот момент, каким оно является в настоящее время. Резервное копирование исходного значения статической переменной отсутствует.
Это означает, что когда статическая переменная 0
когда класс A
связан, A::e()
буду иметь 0
в качестве статического значения; на случай, если это 1
, A::e()
также будет иметь 1
как ценность.
Аналогично для B::e()
тогда как Base::e()
а также A::e()
являются независимыми, так как значения копируются (без ссылок). Он также будет иметь такую же статическую переменную Base::e()
имеет в момент связывания B
,
Я провел некоторое исследование по этой проблеме, и это действительно странно.
Статические свойства внутри методов сохраняют свое состояние между экземплярами объекта. Что может сбивать с толку. Также есть две статики: одна — статическая функция, другая — статическая переменная внутри метода.
Это может быть связано с автозагрузчиком. Я сделал аналогичный пример с вашим, но без использования статических методов, но с использованием статической переменной внутри метода. Результат 1: 1: 1 с использованием как автозагрузчика, так и одного и того же файла.
<?php
class Base
{
public function t()
{
static $number = 0;
$number++;
var_dump($number);
}
public static function e()
{
static $number = 0;
$number++;
var_dump($number);
}
}
$base = new Base();
$base->t();
$a = new A();
$a->t();
$b = new B();
$b->t();
Также, если вы не будете выполнять Base::e()
результат верный.
Я сделал require_once без автозагрузки, и он все еще работает. Так что это определенно из-за автозагрузчика.
Если вы положите
require_once "Base.php";
require_once "A.php";
require_once "B.php";
вместо функции автозагрузчика это работает. Почему я понятия не имею, я пытался найти что-то, рассматривая статические переменные с автозагрузчиком, но безуспешно. Тем не менее, этот ответ может дать вам некоторую подсказку.