如何使用PHP5类创建单例类?
当前回答
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的一个实例。
其他回答
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的一个实例。
这篇文章涵盖了相当广泛的主题: 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.
下面是我的例子,它提供了调用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();
protected static $_instance;
public static function getInstance()
{
if(is_null(self::$_instance))
{
self::$_instance = new self();
}
return self::$_instance;
}
这段代码可以应用于任何类,而无需关心类名。
支持多对象,每类一行:
这个方法将在你想要的任何类上强制单例,你所要做的就是向你想要创建单例的类中添加一个方法,这个方法会为你做这件事。
这也将对象存储在“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();
你可以在任何类中添加这个单例函数,每个类只创建一个实例。
注意:你应该始终将__construct设为private以消除new Class()的使用;实例化。