如何使用PHP5类创建单例类?
当前回答
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();
其他回答
<?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;
respose:
object(DBFactoryChild)#1 (0) {
}
object(DBFactory)#2 (0) {
}
如果你使用的是PHP 5.4: trait,它是一个选项,所以你不必为了拥有单例模式而浪费继承层次结构
还要注意你是使用trait还是扩展Singleton类 如果你不添加以下代码行,就会创建子类的单例:
protected static $inst = null;
在儿童班
意想不到的结果将是:
object(DBFactoryChild)#1 (0) {
}
object(DBFactoryChild)#1 (0) {
}
protected static $_instance;
public static function getInstance()
{
if(is_null(self::$_instance))
{
self::$_instance = new self();
}
return self::$_instance;
}
这段代码可以应用于任何类,而无需关心类名。
这是在数据库类上创建单例的例子
设计模式 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个实例
我很久以前就写过,想在这里分享
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();
你可能应该添加一个私有的__clone()方法来禁止克隆实例。
private function __clone() {}
如果您不包含此方法,则可能出现以下情况
$inst1=UserFactory::Instance(); // to stick with the example provided above
$inst2=clone $inst1;
现在$inst1 !== $inst2 -它们不再是同一个实例了。
推荐文章
- 工厂模式和策略模式之间的区别是什么?
- 在PHP单元测试执行期间,如何在CLI中输出?
- 在PHP中使用heredoc的优势是什么?
- PHP中的echo, print和print_r有什么区别?
- 如何向一个5岁的孩子解释依赖注入?
- 如何将XML转换成PHP数组?
- 如何将对象转换为数组?
- 从IP地址获取位置
- 在Java中使用“final”修饰符
- 获取数组值的键名
- HTTPS和SSL3_GET_SERVER_CERTIFICATE:证书验证失败,CA is OK
- PHP -获取bool值,当为false时返回false
- 在foreach中通过引用传递
- 如何触发命令行PHP脚本的XDebug分析器?
- 如何找出如果你使用HTTPS没有$_SERVER['HTTPS']