The City of knowledge
PHP: Creating a singleton class for serialization
There’s a lot of examples on the internet about creating and using the singleton pattern within your application. From the PHP Docs:
The Singleton pattern applies to situations in which there needs to be a single instance of a class. The most common example of this is a database connection. Implementing this pattern allows a programmer to make this single instance easily accessible by many other objects.
Within any class you want to have use the singleton pattern, just add a getInstance method, like I have in the Obj code listing below. To access that instance use the scope resolution operator:
1 |
$obj = Obj::getInstance();
A problem arises when you want to serialize/unserialize that object from the session variable. The issue is this: When unserialize is called, PHP will attempt to reconstruct the object in question – everything will get created properly but the $instance variable will now be NULL because it would be pointing to the object reference from the previous page. So the next time you would call getInstance, the function would return an entirely new object with no serialized data. All the serialized data would exist in whatever variable the unserialize function was assigned to initially.
Once you understand this subtlety fixing the problem is easy. Create a function called setInstance, which takes in an object reference and assigns the object to the static $instance variable within the class. So once you unserialize your object from the session, immediately call setInstance to let the class know the object exists:
1 |
$obj = unserialize($_SESSION['SessionControl']); $obj->setInstance($obj);
The full code listings follow so you can test this out. Someone out there is probably thinking, why not just called setInstance from within the __wakeup function with $this as a parameter? That won’t work, the object won’t serialize properly.
1 |
<?php
class Obj {
static private $instance = NULL;
public function __construct() { }
public static function getInstance() {
if (self::$instance == NULL) {
self::$instance = new Obj;
}
return self::$instance;
}
public function setInstance($o) {
self::$instance = $o;
}
public function __sleep() {
return array_keys(get_object_vars($this));
}
public function __wakeup() { }
}
?>
1 |
<?php
require 'obj.class.php';
session_start();
if(!empty($_SESSION['SessionControl'])) {
$obj = unserialize($_SESSION['SessionControl']);
$obj->setInstance($obj);
} else {
$obj = Obj::getInstance();
}
function save_session() {
$obj = Obj::getInstance();
$_SESSION['SessionControl'] = serialize($obj);
}
register_shutdown_function(save_session);
?>
| Print article | This entry was posted by moustafa farhat on 29/10/2009 at 8:29 pm, and is filed under php & mysql. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |
