Статические переменные внутри метода

Одна из трудноуловимых ошибок

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

Рассмотрим простой пример -кода:

[-]
View Code PHP
<?php
class A {
    public function __construct()
    {
        static $i = 0;
        ++$i;
        print $i . "\n";
    }
}

$a = new A();
$b = new A();
?>

Внимание, вопрос: что будет выведено на экран (очень хороший вопрос для собеседования)?

Правильный ответ:

[-]
View Code Text
1
2

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

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

Если всё же по каким-либо причинам нужно использовать статическую переменную внутри метода (может быть, статическая переменная класса будет лучшим выбором?), нужно использовать шаблон проектирования “Одиночка” (известный как Singleton):

[-]
View Code PHP
<?php
class A {
    public static function instance()
    {
        static $self = false;
        if (false === $self) {
            $self = new A();
        }

        return $self;
    }

    protected function __construct()
    {
        static $i = 0;
        ++$i;
        print $i . "\n";
    }

    public function __clone()
    {
        trigger_error("Все козлы!", E_USER_ERROR);
    }
}

$a = A::instance();
$b = A::instance();
?>
[-]
View Code Text
1

Документация предлагает альтернативный метод создания Одиночек.

Добавить в закладки

Связанные записи

Автор: Vladimir; опубликовано в: PHP; метки: PHP, ошибка
21
Апр
2009

RSS Комментарии к статье «Статические переменные внутри метода»  »

К статье «Статические переменные внутри метода» комментариев пока нет. Не хотите ли стать первым?

Оставить комментарий к записи «Статические переменные внутри метода»

Вы должны быть авторизованы, чтобы иметь возможность оставить комментарий.

Подписаться, не комментируя