【注意】最后更新于 July 14, 2020,文中内容可能已过时,请谨慎使用。
关于php单例模式的使用
关键点就是:
- 类里面开一个静态变量用于存单例对象
- __construct和__clone变成私有方法, 禁止外部访问
先上代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
<?php
class Demo {
private static $_instance;
public $version;
private function __construct(){
// self::$_instance = $this;
}
private function __clone(){
}
public function test($ver = 1){
$this->version = $ver;
}
// $new=true 时将传出一个新的实例
public static function instance($new = false)
{
if ($new) {
return new self();
}
if (empty(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
}
// 由于 $this 指向的是当前对象, self 指向的是类, 因此 self::$_instance = $this; 会将之后的实例给覆盖掉
$ins1 = Demo::instance();
$ins1->test(3);
echo $ins1->version . PHP_EOL;
$ins3 = Demo::instance(true);
$ins3->test();
echo $ins3->version . PHP_EOL;
$ins2 = Demo::instance();
echo $ins2->version . PHP_EOL;
echo $ins2->version . PHP_EOL;
|
输出:
由于我当时的画蛇添足, 在构造函数里加了一行 self::$_instance = $this;
导致同样的代码输出却是:
后来想了想为什么, 回忆一下得出一个答案, 就是 $this
和self
的区别
$this
可以说是当前对象的标识符, 注意是对象
self
是类的标识符
类
和对象
的区别我认为每个phper都应该知道吧?
回到刚才的问题上, 当我加上 self::$_instance = $this;
时, 代表着把当前对象覆盖到类的静态属性中, 静态属性是和类一起共有同一片内存的, 那么当ins3
里新生成对象的时候, 把原有的类属性给覆盖掉了, 因此之后再使用Demo::instance()
时获得的对象就和$ins3
之前的不一样了
从这里看static
这个关键词使用要慎重, 使用场景只有读的情况可以随意使用, 还能节省一点内存(毕竟每个对象查到的属性都是从同一片内存中读的), 但是涉及到 读写 的时候, 就要想明白它的运行顺序了
文章作者
GPF
上次更新
2020-07-14
(d2c0a52)