Создание шаблона разработки Singleton в PHP5

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

201
задан beatnik 19 January 2015 в 03:53
поделиться

4 ответа

/**
 * Singleton class
 *
 */
final class UserFactory
{
    /**
     * Call this method to get singleton
     *
     * @return UserFactory
     */
    public static function Instance()
    {
        static $inst = null;
        if ($inst === null) {
            $inst = new UserFactory();
        }
        return $inst;
    }

    /**
     * Private ctor so nobody else can instantiate it
     *
     */
    private function __construct()
    {

    }
}

Для использования:

$fact = UserFactory::Instance();
$fact2 = UserFactory::Instance();

$fact == $fact2;

, Но:

$fact = new UserFactory()

Броски ошибка.

Видят http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static для понимания объемов статической переменной и почему установка static $inst = null; работает.

265
ответ дан Arount 23 November 2019 в 05:02
поделиться

Вероятно, необходимо добавить частное __ клон () метод для запрещения клонирования экземпляра.

private function __clone() {}

, Если Вы не включаете этот метод, следующее становится возможным

$inst1=UserFactory::Instance(); // to stick with the example provided above
$inst2=clone $inst1;

теперь $inst1! == $inst2 - они больше не тот же экземпляр.

26
ответ дан Stefan Gehrig 23 November 2019 в 05:02
поделиться

PHP 5.3 позволяет создавать наследуемые синглтоны. class через позднее статическое связывание:

class Singleton
{
    protected static $instance = null;

    protected function __construct()
    {
        //Thou shalt not construct that which is unconstructable!
    }

    protected function __clone()
    {
        //Me not like clones! Me smash clones!
    }

    public static function getInstance()
    {
        if (!isset(static::$instance)) {
            static::$instance = new static;
        }
        return static::$instance;
    }
}

Это решает проблему, заключающуюся в том, что до PHP 5.3 любой класс, расширяющий Singleton, создавал экземпляр своего родительского класса вместо своего собственного.

Теперь вы можете:

class Foobar extends Singleton {};
$foo = Foobar::getInstance();

И $ foo будет экземпляром Foobar вместо экземпляра Singleton.

119
ответ дан 23 November 2019 в 05:02
поделиться

Поддерживает несколько объектов с одной строкой на класс:

Этот метод будет применять одиночные объекты к любому классу, который вы хотите, все, что вам нужно сделать, это добавить 1 метод к классу, который вы хотите создать singleton, и это сделает это за вас.

Здесь также хранятся объекты в классе «SingleTonBase», поэтому вы можете отлаживать все свои объекты, которые вы использовали в своей системе, рекурсивно повторяя объекты SingleTonBase .


Создайте файл с именем SingletonBase.php и включите его в корень вашего скрипта!

Код

abstract class SingletonBase
{
    private static $storage = array();

    public static function Singleton($class)
    {
        if(in_array($class,self::$storage))
        {
            return self::$storage[$class];
        }
        return self::$storage[$class] = new $class();
    }
    public static function storage()
    {
       return self::$storage;
    }
}

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

public static function Singleton()
{
    return SingletonBase::Singleton(get_class());
}

Вот небольшой пример:

include 'libraries/SingletonBase.resource.php';

class Database
{
    //Add that singleton function.
    public static function Singleton()
    {
        return SingletonBase::Singleton(get_class());
    }

    public function run()
    {
        echo 'running...';
    }
}

$Database = Database::Singleton();

$Database->run();

И вы можете просто добавить эту одноэлементную функцию в любой имеющийся у вас класс, и она создаст только 1 экземпляр для каждого класса.

ПРИМЕЧАНИЕ: вы всегда должны делать __construct закрытым, чтобы исключить использование new Class (); экземпляры.

8
ответ дан 23 November 2019 в 05:02
поделиться