PHP и статические переменные в функциях-членах объекта - PullRequest
16 голосов
/ 06 июля 2011

До сегодняшнего дня я думал, что достаточно хорошо понимаю, как работает статический модификатор.Я знаю, что (в терминах непрофессионалов) статическая переменная в функции не «сбрасывается» при вызовах этой функции, и я знаю, что статические переменные и функции в классе доступны путем вызова их через сам класс (не для создания экземпляров)класса).

Моя проблема заключается в следующем: сегодня я обнаружил, что если я объявлю статическую переменную внутри нестатической функции класса, всеэкземпляры этого класса совместно используют эту статическую переменную в отдельных вызовах функции-члена.

Например:

class A {
    public function GetValue() {
        static $value = 0;
        $value++;
        return $value;
    }
}

$instance_1 = new A();
$instance_2 = new A();
echo $instance_1->GetValue();
echo $instance_1->GetValue();

echo $instance_2->GetValue();
echo $instance_2->GetValue();

echo $instance_1->GetValue();
echo $instance_1->GetValue();

Обратите внимание, что функция GetValue не объявлена ​​как статическая или не используется статическим способом(как в, называется на самом классе).

Теперь я всегда предполагал, что это выведет: 121234

Вместо этого я обнаружу, что оно выдаст: 123456

Как я уже сказал, я бы понял это, если статическийпеременная $ value была внутри статической функции.Однако, учитывая, что он находится внутри нестатической функции, я просто предполагал, что он будет «привязан» только к функции «внутри» каждого отдельного экземпляра.

Полагаю, мой вопрос двоякий, тогда ... 1) это ошибка или ожидаемое поведение?2) другие языки обрабатывают эти «статические внутри нестатические» переменные таким же образом, или это уникально для PHP?

Ответы [ 3 ]

7 голосов
/ 06 июля 2011
  1. Это ожидаемо.
  2. Это также относится и к C ++ (и, возможно, к другим).

Вам следует подумать о нестатических функциях-членах классакак будто они были как обычные функции, но с неявным аргументом $this, который автоматически предоставляется интерпретатором.(Именно так они реализованы на большинстве языков.)

5 голосов
/ 06 июля 2011

Я скопировал следующую информацию из этой статьи Джоша Дака: http://joshduck.com/blog/2010/03/19/exploring-phps-static-scoping/

Статические переменные были доступны начиная с PHP 4 и позволяют вам определять постоянные переменные, которые доступны только изтекущая функция.Это позволяет вам инкапсулировать состояние в функцию или метод и может устранить необходимость в классах, для которых достаточно одной функции.

Когда в методе класса определена статическая переменная, они всегда будут ссылаться на классметод был вызван.При этом они действуют почти как свойства, на которые ссылаются статические, хотя есть небольшие различия.

Статические переменные не могут сохранить область действия вызывающего класса.Это может быть потенциально проблематично, если у вас есть унаследованный метод, содержащий статическую переменную, которая вызывается как внутри, так и вне ее класса.

2 голосов
/ 06 июля 2011

Насколько я знаю, все языки со статическими переменными обрабатывают их таким образом.Думайте о статических переменных как о глобальных переменных, к которым можно получить доступ только из определенной области.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...