Pi*R^2

PHP singleton

PHP 单例模式

字数统计: 301阅读时长: 1 min
2018/05/30 Share

单例

单例模式,希望在程序上下文中,仅对对象做一次实例化。

问题

  • clone 会引起出现单例对象有多个实例

避免方式

  • clone 由于clone时,会调用对象的__clone magic method. 因此,可以将__clone 设置为私有,使clone失效。

单例模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Singleton {
private static $instance = NULL;

private function __construct() { }

private function __clone() { }

public static function getInstance() {
if (NULL === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
}

unserialize

将Singleton 将对象序列化,再进行反序列化。可以构造新的单例对象。这种情况下,鸟哥给出的解决方案是:(使用__wakeup() 方法)[http://www.laruence.com/2011/03/18/1909.html]。
但是,通过对比发现,这个代码其实会有问题:

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
<?php
class Singleton {
private static $instance = NULL;
private $data = '';

private function __construct() { }

private function __clone() { }

public function __wakeup() {
self::$instance = $this;
}

public static function getInstance() {
if (NULL === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}

}

$a = Singleton::getInstance();
$b = unserialize(serialize($a));

// false
var_dump($b === $a);

因为unserialize 其实会实例化一个单例对象,和原来实例化的单例对象不是一个对象。因此,会引起dump 不一致的情况。这个暂时无法避免。

原文作者:lpflpf

原文链接:http://blog.lpflpf.cn/passages/php-singleton/

发表日期:2018-05-30 00:00:00

更新日期:2019-09-17 10:04:54

版权声明:本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可

CATALOG
  1. 1. 单例
  2. 2. 问题
  3. 3. 避免方式
  4. 4. 单例模式
  5. 5. unserialize