Создание одноэлементного шаблона проектирования в PHP5


Как можно создать одноэлементный класс, используя классы PHP5?

Author: beatnik, 2008-10-15

20 answers

/**
 * 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;.

 252
Author: nlaq, 2018-01-09 13:22:40

PHP 5.3 позволяет создавать наследуемый одноэлементный класс с помощью поздней статической привязки:

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 любой класс, который расширял одноэлемент, создавал экземпляр своего родительского класса вместо своего собственного.

Теперь вы можете сделать:

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

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

 113
Author: selfawaresoup, 2014-03-04 11:29:39

К сожалению, Ответ Inwdr прерывается, когда существует несколько подклассов.

Вот правильный наследуемый одноэлементный базовый класс.

class Singleton
{
    private static $instances = array();
    protected function __construct() {}
    protected function __clone() {}
    public function __wakeup()
    {
        throw new Exception("Cannot unserialize singleton");
    }

    public static function getInstance()
    {
        $cls = get_called_class(); // late-static-bound class name
        if (!isset(self::$instances[$cls])) {
            self::$instances[$cls] = new static;
        }
        return self::$instances[$cls];
    }
}

Тестовый код:

class Foo extends Singleton {}
class Bar extends Singleton {}

echo get_class(Foo::getInstance()) . "\n";
echo get_class(Bar::getInstance()) . "\n";
 99
Author: mpartel, 2017-05-23 12:34:54

Реальный и современный способ создания одноэлементного шаблона:

<?php

/**
 * Singleton Pattern.
 * 
 * Modern implementation.
 */
class Singleton
{
    /**
     * Call this method to get singleton
     */
    public static function instance()
    {
      static $instance = false;
      if( $instance === false )
      {
        // Late static binding (PHP 5.3+)
        $instance = new static();
      }

      return $instance;
    }

    /**
     * Make constructor private, so nobody can call "new Class".
     */
    private function __construct() {}

    /**
     * Make clone magic method private, so nobody can clone instance.
     */
    private function __clone() {}

    /**
     * Make sleep magic method private, so nobody can serialize instance.
     */
    private function __sleep() {}

    /**
     * Make wakeup magic method private, so nobody can unserialize instance.
     */
    private function __wakeup() {}

}

Так что теперь вы можете использовать его как.

<?php

/**
 * Database.
 *
 * Inherited from Singleton, so it's now got singleton behavior.
 */
class Database extends Singleton {

  protected $label;

  /**
   * Example of that singleton is working correctly.
   */
  public function setLabel($label)
  {
    $this->label = $label;
  }

  public function getLabel()
  {
    return $this->label;
  }

}

// create first instance
$database = Database::instance();
$database->setLabel('Abraham');
echo $database->getLabel() . PHP_EOL;

// now try to create other instance as well
$other_db = Database::instance();
echo $other_db->getLabel() . PHP_EOL; // Abraham

$other_db->setLabel('Priler');
echo $database->getLabel() . PHP_EOL; // Priler
echo $other_db->getLabel() . PHP_EOL; // Priler

Как вы видите, эта реализация намного более гибкая.

 31
Author: Abraham Tugalov, 2017-12-24 22:50:26

Вероятно, вам следует добавить закрытый метод __clone(), чтобы запретить клонирование экземпляра.

private function __clone() {}

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

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

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

 25
Author: Stefan Gehrig, 2008-10-15 07:06:37
protected  static $_instance;

public static function getInstance()
{
    if(is_null(self::$_instance))
    {
        self::$_instance = new self();
    }
    return self::$_instance;
}

Этот код может применяться для любого класса, не заботясь о его имени класса.

 10
Author: hungneox, 2012-01-18 04:20:25
<?php
/**
 * Singleton patter in php
 **/
trait SingletonTrait {
   protected static $inst = null;

  /**
   * call this method to get instance
   **/
   public static function getInstance(){
      if (static::$inst === null){
         static::$inst = new static();
      }
      return static::$inst;
  }

  /**
   * protected to prevent clonning 
   **/
  protected function __clone(){
  }

  /**
   * protected so no one else can instance it 
   **/
  protected function __construct(){
  }
}

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

/**
 *  example of class definitions using SingletonTrait
 */
class DBFactory {
  /**
   * we are adding the trait here 
   **/
   use SingletonTrait;

  /**
   * This class will have a single db connection as an example
   **/
  protected $db;


 /**
  * as an example we will create a PDO connection
  **/
  protected function __construct(){
    $this->db = 
        new PDO('mysql:dbname=foodb;port=3305;host=127.0.0.1','foouser','foopass');
  }
}
class DBFactoryChild extends DBFactory {
  /**
   * we repeating the inst so that it will differentiate it
   * from UserFactory singleton
   **/
   protected static $inst = null;
}


/**
 * example of instanciating the classes
 */
$uf0 = DBFactoryChild::getInstance();
var_dump($uf0);
$uf1 = DBFactory::getInstance();
var_dump($uf1);
echo $uf0 === $uf1;

Передышка:

object(DBFactoryChild)#1 (0) {
}
object(DBFactory)#2 (0) {
}

Если вы используете PHP 5.4: черта характера это вариант, поэтому вам не нужно тратить иерархию наследования, чтобы иметь Одноэлементный шаблон

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

   protected static $inst = null;

В дочернем классе

Неожиданным результатом будет:

object(DBFactoryChild)#1 (0) {
}
object(DBFactoryChild)#1 (0) {
}
 10
Author: jose segura, 2013-05-18 13:14:31

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

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

Это также сохраняет объекты в классе "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 экземпляр для каждого класса.

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

 6
Author: RobertPitt, 2014-07-03 20:15:42
class Database{

        //variable to hold db connection
        private $db;
        //note we used static variable,beacuse an instance cannot be used to refer this
        public static $instance;

        //note constructor is private so that classcannot be instantiated
        private function __construct(){
          //code connect to database  

         }     

         //to prevent loop hole in PHP so that the class cannot be cloned
        private function __clone() {}

        //used static function so that, this can be called from other classes
        public static function getInstance(){

            if( !(self::$instance instanceof self) ){
                self::$instance = new self();           
            }
             return self::$instance;
        }


        public function query($sql){
            //code to run the query
        }

    }


Access the method getInstance using
$db = Singleton::getInstance();
$db->query();
 5
Author: rizon, 2013-04-07 09:43:41

Вся эта сложность ("поздняя статическая привязка"... harumph) для меня является просто признаком сломанной модели объекта/класса PHP. Если бы объекты класса были объектами первого класса (см. Python), то "$_instance" был бы экземпляром класса переменной - членом объекта класса, в отличие от члена/свойства его экземпляров, а также в отличие от общего доступа его потомков. В мире Smalltalk это разница между "переменной класса" и "экземпляром класса переменная".

В PHP мне кажется, что нам нужно принять близко к сердцу руководство о том, что шаблоны являются руководством к написанию кода - возможно, мы могли бы подумать об одноэлементном шаблоне, но попытка написать код, который наследуется от фактического "одноэлементного" класса, выглядит ошибочной для PHP (хотя я предположил, что какая-то предприимчивая душа могла бы создать подходящее ключевое слово SVN).

Я продолжу просто кодировать каждый синглтон отдельно, используя общий шаблон.

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

 3
Author: Tom Stambaugh, 2013-08-09 21:10:57

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

Вот пример: я решил запустить свой собственный движок MVC и шаблонов, потому что хотел что-то действительно легкое. Однако данные, которые я хочу отобразить, содержат много специальных математических символов, таких как ≥ и μ, и что у вас есть... Данные хранятся в моей базе данных в виде фактического символа UTF-8, а не в кодировке, предварительно закодированной в HTML, потому что мое приложение может предоставлять другие форматы, такие как PDF и CSV, в дополнение к HTML. Подходящее место для форматирования HTML находится внутри шаблона ("просмотр", если хотите), который отвечает за отображение этого раздела страницы (фрагмента). Я хочу преобразовать их в соответствующие HTML-объекты, но функция PHPS get_html_translation_table() это не очень быстро. Имеет смысл извлечь данные один раз и сохранить их в виде массива, сделав их доступными для всех пользователей. Вот образец, который я собрал, чтобы проверить скорость. Предположительно, это будет работать независимо от того, были ли другие методы, которые вы используете (после получения экземпляра), статическими или нет.

class EncodeHTMLEntities {

    private static $instance = null;//stores the instance of self
    private $r = null;//array of chars elligalbe for replacement

    private function __clone(){
    }//disable cloning, no reason to clone

    private function __construct()
    {
        $allEntities = get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES);
        $specialEntities = get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES);
        $this->r = array_diff($allEntities, $specialEntities);
    }

    public static function replace($string)
    {
        if(!(self::$instance instanceof self) ){
            self::$instance = new self();
        }
        return strtr($string, self::$instance->r);
    }
}
//test one million encodings of a string
$start = microtime(true);
for($x=0; $x<1000000; $x++){
    $dump = EncodeHTMLEntities::replace("Reference method for diagnosis of CDAD, but clinical usefulness limited due to extended turnaround time (≥96 hrs)");
}
$end = microtime(true);
echo "Run time: ".($end-$start)." seconds using singleton\n";
//now repeat the same without using singleton
$start = microtime(true);
for($x=0; $x<1000000; $x++){
    $allEntities = get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES);
    $specialEntities = get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES);
    $r = array_diff($allEntities, $specialEntities);
    $dump = strtr("Reference method for diagnosis of CDAD, but clinical usefulness limited due to extended turnaround time (≥96 hrs)", $r);
}
$end = microtime(true);
echo "Run time: ".($end-$start)." seconds without using singleton";

В принципе, я видел типичные результаты, подобные этому:

php test.php
Run time: 27.842966794968 seconds using singleton
Run time: 237.78191494942 seconds without using singleton

Поэтому, хотя я, конечно, не эксперт, я не вижу более удобного и надежного способа уменьшить накладные расходы на медленно запрашивает какие-то данные, делая их очень простыми (одна строка кода для выполнения того, что вам нужно). Конечно, в моем примере есть только один полезный метод, и поэтому он не лучше, чем глобально определенная функция, но как только у вас будет два метода, вы захотите сгруппировать их вместе, верно? Я далеко от базы?

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

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

 2
Author: user2009125, 2017-05-18 09:52:54

На самом деле вам не нужно использовать одноэлементный шаблон, потому что он считается антипаттером. В принципе, есть много причин вообще не реализовывать этот шаблон. Прочитайте это, чтобы начать с: Рекомендации по одноэлементным классам PHP.

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

Вот для чего я пришел с тем, чтобы решить эту проблему.

<?php
namespace wl;


/**
 * @author DevWL
 * @dosc allows only one instance for each extending class.
 * it acts a litle bit as registry from the SingletonClassVendor abstract class point of view
 * but it provides a valid singleton behaviour for its children classes
 * Be aware, the singleton pattern is consider to be an anti-pattern
 * mostly because it can be hard to debug and it comes with some limitations.
 * In most cases you do not need to use singleton pattern
 * so take a longer moment to think about it before you use it.
 */
abstract class SingletonClassVendor
{
    /**
     *  holds an single instance of the child class
     *
     *  @var array of objects
     */
    protected static $instance = [];

    /**
     *  @desc provides a single slot to hold an instance interchanble between all child classes.
     *  @return object
     */
    public static final function getInstance(){
        $class = get_called_class(); // or get_class(new static());
        if(!isset(self::$instance[$class]) || !self::$instance[$class] instanceof $class){
            self::$instance[$class] = new static(); // create and instance of child class which extends Singleton super class
            echo "new ". $class . PHP_EOL; // remove this line after testing
            return  self::$instance[$class]; // remove this line after testing
        }
        echo "old ". $class . PHP_EOL; // remove this line after testing
        return static::$instance[$class];
    }

    /**
     * Make constructor abstract to force protected implementation of the __constructor() method, so that nobody can call directly "new Class()".
     */
    abstract protected function __construct();

    /**
     * Make clone magic method private, so nobody can clone instance.
     */
    private function __clone() {}

    /**
     * Make sleep magic method private, so nobody can serialize instance.
     */
    private function __sleep() {}

    /**
     * Make wakeup magic method private, so nobody can unserialize instance.
     */
    private function __wakeup() {}

}

Используйте пример:

/**
 * EXAMPLE
 */

/**
 *  @example 1 - Database class by extending SingletonClassVendor abstract class becomes fully functional singleton
 *  __constructor must be set to protected becaouse: 
 *   1 to allow instansiation from parent class 
 *   2 to prevent direct instanciation of object with "new" keword.
 *   3 to meet requierments of SingletonClassVendor abstract class
 */
class Database extends SingletonClassVendor
{
    public $type = "SomeClass";
    protected function __construct(){
        echo "DDDDDDDDD". PHP_EOL; // remove this line after testing
    }
}


/**
 *  @example 2 - Config ...
 */
class Config extends SingletonClassVendor
{
    public $name = "Config";
    protected function __construct(){
        echo "CCCCCCCCCC" . PHP_EOL; // remove this line after testing
    }
}

Просто чтобы доказать, что это работает так, как ожидалось:

/**
 *  TESTING
 */
$bd1 = Database::getInstance(); // new
$bd2 = Database::getInstance(); // old
$bd3 = Config::getInstance(); // new
$bd4 = Config::getInstance(); // old
$bd5 = Config::getInstance(); // old
$bd6 = Database::getInstance(); // old
$bd7 = Database::getInstance(); // old
$bd8 = Config::getInstance(); // old

echo PHP_EOL."COMPARE ALL DATABASE INSTANCES".PHP_EOL;
var_dump($bd1);
echo '$bd1 === $bd2' . ($bd1 === $bd2)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd2 === $bd6' . ($bd2 === $bd6)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd6 === $bd7' . ($bd6 === $bd7)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE

echo PHP_EOL;

echo PHP_EOL."COMPARE ALL CONFIG INSTANCES". PHP_EOL;
var_dump($bd3);
echo '$bd3 === $bd4' . ($bd3 === $bd4)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd4 === $bd5' . ($bd4 === $bd5)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd5 === $bd8' . ($bd5 === $bd8)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
 2
Author: DevWL, 2018-01-08 20:45:59

Эта статья довольно широко охватывает тему: http://www.phptherightway.com/pages/Design-Patterns.html#singleton

Обратите внимание на следующее:

  • Конструктор __construct() объявлен как protected, чтобы предотвратить создание нового экземпляра вне класса с помощью оператора new.
  • Магический метод __clone() объявлен как private, чтобы предотвратить клонирование экземпляра класса с помощью оператора clone.
  • Волшебный метод __wakeup() объявляется как private, чтобы предотвратить несериализацию экземпляра класса с помощью глобальной функции unserialize().
  • Новый экземпляр создается с помощью поздней статической привязки в методе статического создания getInstance() с ключевым словом static. Это позволяет создавать подклассы class Singleton в примере.
 1
Author: Krzysztof Przygoda, 2015-12-17 19:21:10

Я давно написал, что хотел бы поделиться здесь

class SingletonDesignPattern {

    //just for demo there will be only one instance
    private static $instanceCount =0;

    //create the private instance variable
    private static $myInstance=null;

    //make constructor private so no one create object using new Keyword
    private function  __construct(){}

    //no one clone the object
    private function  __clone(){}

    //avoid serialazation
    public function __wakeup(){}

    //ony one way to create  object
    public static  function  getInstance(){

        if(self::$myInstance==null){
            self::$myInstance=new SingletonDesignPattern();
            self::$instanceCount++;
        }
        return self::$myInstance;
    }

    public static function getInstanceCount(){
        return self::$instanceCount;
    }

}

//now lets play with singleton design pattern

$instance = SingletonDesignPattern::getInstance();
$instance = SingletonDesignPattern::getInstance();
$instance = SingletonDesignPattern::getInstance();
$instance = SingletonDesignPattern::getInstance();

echo "number of instances: ".SingletonDesignPattern::getInstanceCount();
 1
Author: Gyaneshwar Pardhi, 2017-01-31 07:00:50

Я согласен с первым ответом, но я бы также объявил класс окончательным, чтобы его нельзя было расширить, поскольку расширение синглтона нарушает шаблон синглтона. Кроме того, переменная экземпляра должна быть закрытой, чтобы к ней нельзя было получить прямой доступ. Также сделайте метод __clone закрытым, чтобы вы не могли клонировать одноэлементный объект.

Ниже приведен пример кода.

/**
 * Singleton class
 *
 */
final class UserFactory
{
    private static $_instance = null;

    /**
     * Private constructor
     *
     */
    private function __construct() {}

    /**
     * Private clone method
     *
     */
     private function __clone() {}

    /**
     * Call this method to get singleton
     *
     * @return UserFactory
     */
    public static function getInstance()
    {
        if (self::$_instance === null) {
            self::$_instance = new UserFactory();
        }
        return self::$_instance;
    }
}

Пример использования

$user_factory = UserFactory::getInstance();

Что это мешает вам делать (что нарушило бы синглтон шаблон..

ВЫ НЕ МОЖЕТЕ ЭТОГО СДЕЛАТЬ!

$user_factory = UserFactory::$_instance;

class SecondUserFactory extends UserFactory { }
 0
Author: Joseph Crawford, 2013-10-08 22:51:27

Это должен быть правильный путь Синглтона.

class Singleton {

    private static $instance;
    private $count = 0;

    protected function __construct(){

    }

    public static function singleton(){

        if (!isset(self::$instance)) {

            self::$instance = new Singleton;

        }

        return self::$instance;

    }

    public function increment()
    {
        return $this->count++;
    }

    protected function __clone(){

    }

    protected function __wakeup(){

    }

} 
 0
Author: Mário Kapusta, 2013-11-13 16:33:07

Мне понравился метод @jose-segura использования признаков, но мне не понравилась необходимость определения статической переменной в подклассах. Ниже приведено решение, которое позволяет избежать этого, кэшируя экземпляры в статической локальной переменной в заводском методе, индексированном по имени класса:

<?php
trait Singleton {

  # Single point of entry for creating a new instance. For a given
  # class always returns the same instance.
  public static function instance(){
    static $instances = array();
    $class = get_called_class();
    if( !isset($instances[$class]) ) $instances[$class] = new $class();
    return $instances[$class];
  }

  # Kill traditional methods of creating new instances
  protected function __clone() {}
  protected function __construct() {}
}

Использование такое же, как у @jose-segura, только нет необходимости в статической переменной в подклассах.

 0
Author: Eric Anderson, 2014-06-02 15:39:11

Класс базы данных, который проверяет, существует ли какой-либо существующий экземпляр базы данных, он вернет предыдущий экземпляр.

   class Database {  
        public static $instance;  
         public static function getInstance(){  
            if(!isset(Database::$instance) ) {  
                Database::$instance = new Database();  
            }  
           return Database::$instance;  
         }  
         private function __cunstruct() {  
           /* private and cant create multiple objects */  
         }  
         public function getQuery(){  
            return "Test Query Data";  
         }  
    }  
    $dbObj = Database::getInstance();  
    $dbObj2 = Database::getInstance();  
    var_dump($dbObj);  
    var_dump($dbObj2);  


/* 
After execution you will get following output: 

object(Database)[1] 
object(Database)[1] 

*/  

Ссылка http://www.phptechi.com/php-singleton-design-patterns-example.html

 0
Author: sunil rajput, 2014-12-08 15:49:43

Это пример создания синглтона в классе базы данных

Шаблоны проектирования 1) синглтон

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

     return Database::$instance;
    }

  }

  $db=Database::getInstance();
  $db2=Database::getInstance();
  $db3=Database::getInstance();

  var_dump($db);
  var_dump($db2);
  var_dump($db3);

Тогда выход -

  object(Database)[1]
  object(Database)[1]
  object(Database)[1]

Используйте только один экземпляр, а не создавайте 3 экземпляра

 0
Author: Surendra Kumar Ahir, 2016-01-02 08:21:56

Вот мой пример, который предоставляет возможность вызывать как $var =новый синглтон(), а также создавать 3 переменные для проверки, создает ли он новый объект:

class Singleton{

    private static $data;

    function __construct(){
        if ($this::$data == null){
            $this->makeSingleton();
        }
        echo "<br/>".$this::$data;
    }

    private function makeSingleton(){
        $this::$data = rand(0, 100);
    }

    public function change($new_val){
        $this::$data = $new_val;
    }

    public function printme(){
        echo "<br/>".$this::$data;
    }

}


$a = new Singleton();
$b = new Singleton();
$c = new Singleton();

$a->change(-2);
$a->printme();
$b->printme();

$d = new Singleton();
$d->printme();
 -3
Author: bboydev, 2013-02-04 08:14:59