PHP: проблемы с использованием шаблона Singleton и понимания метода __clone - PullRequest
0 голосов
/ 31 января 2012

Я пытаюсь реализовать шаблон синглтона в php, как описано здесь в Примере №2: http://www.php.net/singleton

Когда я запускаю пример кода

$singleton = Example::singleton(); // prints "Creating new instance."
echo $singleton->increment(); // 0
echo $singleton->increment(); // 1

$singleton = Example::singleton(); // reuses existing instance now
echo $singleton->increment(); // 2
echo $singleton->increment(); // 3

, он всегда заканчивается FatalОшибка «Клонирование не допускается».непосредственно после «Создание нового экземпляра».

Я ожидаю, что у php нет причин для вызова метода __clone.В другом моем реальном жизненном проекте я хочу иметь одноэлементный PlayerManager, который содержит объекты Player в массиве (загружается только один раз в __construct) и имеет функции, такие как GetPlayers () или GetPlayersByID ($ id).

В моем сценарии я пишу что-то вроде

$pm = PlayerManager::GetInstance();
$p1 = $pm->GetPlayerByID(0);
echo $p1->SomeNumber; //100

$p1->SomeNumber = 200;
$p2 = $pm->GetPlayerByID(0);
echo $p2->SomeNumber; //100 and not 200, as I would expect

Может кто-нибудь дать мне несколько советов, как правильно реализовать PlayerManager с использованием шаблона Singleton?Я не уверен, что это только проблема с синглтоном или проблема с возвратом ссылок на объекты ...

1 Ответ

1 голос
/ 31 января 2012

Я не уверен, почему вы получаете эту ошибку (опубликуйте свой синглтон-класс, если вам нужна помощь с этим). Хотя я всегда предпочитал эту версию той, которую вы используете, она немного проще: http://www.talkphp.com/advanced-php-programming/1304-how-use-singleton-design-pattern.html

Итак, с учетом вышеизложенного ваш код будет выглядеть так:

class Counter
{
    $CurrentValue = 0;

    // Store the single instance of Database 
    private static $m_pInstance; 

    private function __construct() { } 

    public static function getInstance() 
    { 
        if (!self::$m_pInstance) 
        { 
            self::$m_pInstance = new Counter(); 
        } 

        return self::$m_pInstance; 
    }

    public function increment ($by)
    {
        $this->CurrentValue += $by;
        return $this->CurrentValue;
    }
    public function getValue ()
    {
        return $this->CurrentValue;
    }
}

И использовать:

$counter = Counter::getInstance();
echo $counter->increment(); // 0
echo $counter->increment(); // 1

$counter = null;

$counter = Counter::getInstance(); // reuses existing instance now
echo $counter->increment(); // 2
echo $counter->increment(); // 3

Расскажите, как это работает для вас.

...