单例模式,意思大概是一个类有且只能有一个实例,如果用任何方法重复创建的实例,都必须返回最初的那个,或者不返回。
第一步
意思很明显了,所以,我们首先需要一个类,姑且就叫作小明吧。
class Xiaoming
{
}
$xiaoming = new Xiaoming();
emmmmm,这个时候就算我继续new一个对象,姑且就叫做$xiaoming2吧,也是可以的,而且他们会在堆内存里面创建不同的对象。和我们想要的同一个对象就不一样了。
考虑一个问题,就算我能创建两个一模一样的对象,那么怎么样才能区分它们是一样的还是不同的呢。
答案是三个等号===,三个等号在php中代表值和类型都相等,这样就可以基本保证两个实例是同一个对象。
class Xiaoming
{
}
$xiaoming1 = new Xiaoming();
$xiaoming2 = new Xiaoming();
if($xiaoming1 === $xiaoming2)
{
echo '是同一个';die;
}
echo '不是同一个';
结果是这样的
第二步
那么开始考虑怎么让这个类创建实例的时候永远返回的就是同一个类。
1 从构造方法开始返回的就是一个一个静态的实例
2 由于需要一个静态的实例变量
class Xiaoming
{
private static $xiaoming = null;
public function __construct()
{
return self::$xiaoming;
}
}
$xiaoming1 = new Xiaoming();
$xiaoming2 = new Xiaoming();
var_dump($xiaoming1);
echo '<br>';
var_dump($xiaoming2);
echo '<br>';
if($xiaoming1 === $xiaoming2)
{
echo '是同一个';die;
}
echo '不是同一个';
大概变成了这个样子,按照我的理解,应该是可以的,他们最后都会返回null值才对。但是还是不行,因为输出出来是这个样子的
第三步
说明构造函数可能对我们的初始化有影响,那么干脆点,不允许外部调用构造函数了,构造函数改成私有的
自己写一个获取对象实例的函数调用构造函数,如果这个类已经创建过了,那么就直接返回创建过的实例,创建过的实例放到自带的静态变量里头
1 起一个新的函数getinstance()
2 限制原来的构造函数 改成private
3 新的实例只能用新创建的函数获取,self::$xiaoming = new Xiaoming()
4 如果实例已经被创建,则返回自身静态的实例 return self::$xiaoming
class Xiaoming
{
private static $xiaoming = null;
private final function __construct()
{
//return self::$xiaoming;
}
public static function getinstance()
{
if(self::$xiaoming == null)
{
self::$xiaoming = new Xiaoming();
}
return self::$xiaoming;
}
}
$xiaoming1 = Xiaoming::getinstance();
$xiaoming2 = Xiaoming::getinstance();
var_dump($xiaoming1);
echo '<br>';
var_dump($xiaoming2);
echo '<br>';
if($xiaoming1 === $xiaoming2)
{
echo '是同一个';die;
}
echo '不是同一个';
运行结果如上
当然了,if条件判断也可以以下关键字去写: instanceof
php中 instanceof有什么作用
作用:(1)判断一个对象是否是某个类的实例,(2)判断一个对象是否实现了某个接口。
顺便呢,在构造方法里头加一个final关键字,以防继承的时候被修改了权限
第四步
基本上来看已经成功了,但是要考虑克隆方法
需要禁掉克隆方法;
class Xiaoming
{
private static $xiaoming = null;
private final function __construct()
{
//return self::$xiaoming;
}
public static function getinstance()
{
if(self::$xiaoming == null)
{
self::$xiaoming = new Xiaoming();
}
return self::$xiaoming;
}
private final function __clone()
{
}
}
大功告成
额外步
emmmmm,哪里怪怪的,不专业,把名字改改
class Singleton
{
private static $ins= null;
private final function __construct()
{
//return self::$xiaoming;
}
public static function getinstance()
{
if(self::$ins == null)
{
self::$ins = new Singleton();
}
return self::$ins;
}
private final function __clone()
{
}
}
这样就比较像那么回事了