#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. Можете ли вы также попытаться опубликовать некоторые пояснения к написанному вами коду?