Одноэлементный шаблон в php

#php #singleton

#php #Одноэлементный

Вопрос:

 class SingleTon
{
    private static $instance;

    private function __construct()
    {
    }

    public function getInstance() {
        if($instance === null) {
            $instance = new SingleTon();
        }
        return $instance;
    }
}
 

Приведенный выше код изображает одноэлементный шаблон из этой статьи. http://www.hiteshagrawal.com/php/singleton-class-in-php-5

Я не понял одну вещь. Я загружаю этот класс в свой проект, но как я мог бы изначально создать объект Singleton. Буду ли я вызывать так Singelton :: getInstance()

Может ли кто-нибудь показать мне одноэлементный класс, в котором установлено соединение с базой данных?

Комментарии:

1. Какая часть if($instance === null) { $instance = new SingleTon(); } вам непонятна? (Примечание: это Singleton, а не SingleTon, Singelon или Singelton)

Ответ №1:

Пример того, как вы могли бы реализовать одноэлементный шаблон для класса базы данных, можно увидеть ниже:

 class Database implements Singleton {
    private static $instance;
    private $pdo;

    private function __construct() {
        $this->pdo = new PDO(
            "mysql:host=localhost;dbname=database",
            "user",
            "password"
        );
    }

    public static function getInstance() {
        if(self::$instance === null) {
            self::$instance = new Database();
        }
        return self::$instance->pdo;
    }
}
 

Вы могли бы использовать класс следующим образом:

 $db = Database::getInstance();
// $db is now an instance of PDO
$db->prepare("SELECT ...");

// ...

$db = Database::getInstance();
// $db is the same instance as before
 

И для справки, Singleton интерфейс будет выглядеть так:

 interface Singleton {
    public static function getInstance();
}
 

Комментарии:

1. Как выглядел бы мой родительский одноэлементный конструктор parent::__construct(«mysql:host=localhost;dbname=database», «user», «password»);

2. @theJava: В примере я расширяю класс PDO, поэтому PDO __construct() будет этим методом.

3. @theJava: поскольку у одиночных элементов должен быть getInstance() метод, интерфейс определит, что вы должны объявить его в своем классе.

4. @TimCooper $instance = новая база данных(); должно быть self::$instance = новая база данных();

5. @hafichuk: Спасибо. Я пропустил это.

Ответ №2:

Да, вы должны вызывать с помощью

 SingleTon::getInstance();
 

В первый раз он проверит частный var $instance , который равен null, и поэтому скрипт будет запущен $instance = new SingleTon(); .

Для класса базы данных это то же самое. Это экстракт класса, который я использую в Zend Framework:

 class Application_Model_Database
{
   /**
    *
    * @var Zend_Db_Adapter_Abstract
    */
   private static $Db = NULL;

   /**
    *
    * @return Zend_Db_Adapter_Abstract
    */
   public static function getDb()
   {
      if (self::$Db === NULL)
         self::$Db = Zend_Db_Table::getDefaultAdapter();
      return self::$Db;
   }
}
 

Примечание: шаблон является одноэлементным, а не одноэлементным.

Ответ №3:

Несколько исправлений в вашем коде. Вы должны убедиться, что метод getInstance является «статическим», что означает, что это метод класса, а не метод экземпляра. Вам также необходимо ссылаться на атрибут через ключевое слово ‘self’.

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

 <?
class Singleton
{
    private static $_instance;

    private function __construct() { }
    private final function __clone() { }

    public static function getInstance() {
        if(self::$_instance === null) {
            self::$_instance = new Singleton();
        }
        return self::$_instance;
    }
}
?>

$mySingleton = Singleton::getInstance();
 

Единственное, чего нельзя делать, это то, что если вы планируете проводить модульное тестирование, использование одноэлементного шаблона вызовет у вас некоторые трудности. Смотрите http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html

Ответ №4:

 class Database{
    private static $link=NULL;
    private static $getInitial=NULL;

    public static function getInitial() {
         if (self::$getInitial == null)
         self::$getInitial = new Database();
         return self::$getInitial;
    }
    public function __construct($server = 'localhost', $username = 'root', $password ='tabsquare123', $database = 'cloud_storage') {

         self::$link = mysql_connect($server, $username, $password);
         mysql_select_db($database,self::$link);
         mysql_query("SET CHARACTER SET utf8", self::$link); 
         mysql_query("SET NAMES 'utf8'", self::$link); 
         return self::$link;
    }

    function __destruct(){
          mysql_close(self::$link);
    }
}
 

Комментарии:

1. Можете ли вы также попытаться опубликовать некоторые пояснения к написанному вами коду?