如何使用PHP5类创建单例类?
当前回答
下面是我的例子,它提供了调用as $var = new Singleton()的能力,并创建了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();
其他回答
数据库类,检查是否有任何现有的数据库实例,它将返回先前的实例。
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]
*/
Ref http://www.phptechi.com/php-singleton-design-patterns-example.html
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之前,任何扩展了Singleton的类都会生成父类的实例,而不是它自己的实例。
现在你可以做:
class Foobar extends Singleton {};
$foo = Foobar::getInstance();
$foo将是Foobar的一个实例而不是Singleton的一个实例。
/**
* Singleton class
*
*/
final class UserFactory
{
private static $inst = null;
// Prevent cloning and de-serializing
private function __clone(){}
private function __wakeup(){}
/**
* Call this method to get singleton
*
* @return UserFactory
*/
public static function Instance()
{
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;
But:
$fact = new UserFactory()
抛出错误。
参见http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static了解静态变量的作用域以及为什么设置static $inst = null;的工作原理。
这篇文章涵盖了相当广泛的主题: http://www.phptherightway.com/pages/Design-Patterns.html#singleton
Note the following: The constructor __construct() is declared as protected to prevent creating a new instance outside of the class via the new operator. The magic method __clone() is declared as private to prevent cloning of an instance of the class via the clone operator. The magic method __wakeup() is declared as private to prevent unserializing of an instance of the class via the global function unserialize(). A new instance is created via late static binding in the static creation method getInstance() with the keyword static. This allows the subclassing of the class Singleton in the example.
这是在数据库类上创建单例的例子
设计模式 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个实例
推荐文章
- 如何将XML转换成PHP数组?
- 如何将对象转换为数组?
- 从IP地址获取位置
- 在Java中使用“final”修饰符
- 获取数组值的键名
- HTTPS和SSL3_GET_SERVER_CERTIFICATE:证书验证失败,CA is OK
- PHP -获取bool值,当为false时返回false
- 在foreach中通过引用传递
- 如何触发命令行PHP脚本的XDebug分析器?
- 如何找出如果你使用HTTPS没有$_SERVER['HTTPS']
- 我怎么知道什么时候创建一个接口?
- 更好的方法检查变量为null或空字符串?
- 当使用Composer的开发/生产开关时,如何正确部署?
- 自动删除Laravel (Eloquent ORM)中的相关行
- 在取消设置元素后重新设置数组键