note 83343 deleted from language.oop5.patterns by danbrown
| From: | danbrown@php.net | Date: | Sun, 23 Jan 2011 16:41:12 +0000 |
| Subject: | note 83343 deleted from language.oop5.patterns by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-176103@lists.php.net to get a copy of this message | ||
Note Submitter: krisdover at hotmail dot com
----
The Singleton pattern shown in the above example can still be broken by object serialization. e.g.
<?
class SingleFoo{
private static $instance;
public $identity = "in the end, there can be only one foo\n";
private function __construct() {}
public static function getInstance(){
if(!self::$instance){
self::$instance = new SingleFoo();
}
return self::$instance;
}
public function setIdentity($identity){
$this->identity = $identity;
}
public function getIdentity(){
return $this->identity;
}
}
$foo = unserialize( serialize(SingleFoo::getInstance()) );
$foo->setIdentity("new foo on the block\n");
print(SingleFoo::getInstance()->getIdentity());
print($foo->getIdentity());
// result:
// in the end, there can be only one foo
// new foo on the block
?>
A possible solution to this problem involves using the magic method __wakeup() in the Singleton
class to enforce the Singleton pattern during unserialization:
<?
class Singleton{
// ....
public function __wakeup(){
if(!self::$instance){
self::$instance = $this;
}else{
trigger_error("Unserializing this instance while another exists voilates the
Singleton pattern",
E_USER_ERROR);
}
}
// ....
}
?>
The unserialization would be permitted if it does not result in additional instances of the
Singleton, and instances restored in this way would still be accessible via the Singleton static
factory method.
Kris Dover