PHP: The magic functions __sleep and __wakeup - Manual

downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

References inside the constructor Serializing objects - objects in sessions

Last updated: Fri, 26 Jan 2007

view this page in

# The magic functions `__sleep` and `__wakeup`

serialize() checks if your class has a function with the magic name `__sleep`. If so, that function is being run prior to any serialization. It can clean up the object and is supposed to return an array with the names of all variables of that object that should be serialized.

The intended use of `__sleep` is to close any database connections that object may have, committing pending data or perform similar cleanup tasks. Also, the function is useful if you have very large objects which need not be saved completely.

Conversely, unserialize() checks for the presence of a function with the magic name `__wakeup`. If present, this function can reconstruct any resources that object may have.

The intended use of `__wakeup` is to reestablish any database connections that may have been lost during serialization and perform other reinitialization tasks.

add a note User Contributed Notes
The magic functions __sleep and __wakeup
phreak at aon dot at
18-Feb-2007 02:38
`I just noticed the following:
if you use $this inside __sleep, it does not change the original instance, because its a copy. very naughty.
the only workaround for this reference - copy problem with __sleep i found is to use global variables, which is not very beautiful.
<?php
class A {
var $e;
function __sleep() {
$this->e = 'sleeping...';
return array('e');
}
}
$a = new A();
$a->e = 'MyValue';
echo serialize($a)."\n";
echo $a->e; // echoes "MyValue" - not "sleeping..."
?>
interesting to note:
<?php
echo serialize(&$a); // does what is expected
?>
BUT: thats deprecated.`
cwfsp at hizzotmail dizzot cizzom nospam
20-Sep-2005 06:35
`Following up to rkelly at NO dot whitley dot unimelb dot SPAM dot edu dot au's note regarding __sleep()
__sleep expects you to return an array of object variables that are allowed to be serialized.
Not returning this array -will- result in your object not being serialized, and -will- cause headaches. If you need __sleep() to do cleanup:
1) do your cleanup
2) return the object variables in an array using the code from the comment from php at sharpdreams dot com (below)
search phrases to help people find this info:
php object will not (does not) work in session
session object will not work in subsequent page views
my object won't show up on next page`
06-Jan-2005 08:09
`There is a weird behavior occuring when serializing/unserializing a class derived from a (abstract) base class. The base may not unserialize itself if it has private members, because even if the derived class' __wakeup function is contains only parent::__wakeup() as its code, the unserialization takes place from the children's __wakeup() function and the parent's __wakeup() wont be called (as of php 5.0.3) and hence, private members from the parent wont ever be restored, even though they do serialize properly. This might/might not be a bug, but it is evil and is works not nicely with object oriented concepts. A workaround would be to put the base class' members protected or to (un)serialize manually the base class' via its derived class' __sleep() and __wakeup()`
j dot gizmo at aon dot at
28-Sep-2004 05:48
`re: last post
are you sure the problem with global variables doesn't arise from the use of references?
<?
class test
{
function __wakeup ()
{
global $link;
//will not work
$link =& $this;
//will work
$GLOBALS['link'] =& $this;
}
}
?>
see the section on references for further details`
Eric at Footsteps dot nl
01-Jul-2004 03:29
`It appears, that although __wakeup() can read from global defined variables // global $variable; , changing those variables don't affect them outside __wakeup().
The same thing seems to happen when an object is being serialized in a session when you start your session. if your __wakeup() function tries to set something within your session it might get overwritten/lost. In my situation it happened when an object in an object in a session tried to change a session variable on __wakup().
In my case, putting the variable in $GLOBAL and moving the variable in the session at a later time, is a satisfying workaround.`
php at sharpdreams dot com
09-May-2004 12:11
`To cut down the code in jan at sorgalla dot com's solution:
<?php
class foo {
function __sleep() {
return( array_keys( get_object_vars( &$this ) ) );
}
}
?>`
jacobmather at dwsc dot net
21-Nov-2003 04:23
`Something interesting to point out...
the magic __wakeup() function has access to global variables... such as... $_POST! How interesing... I think i'm going to use this to enhance template handeling. Interesting to think of though. Just make your template object referance the information it needs from inside the __wakeup routine, and make it display the initial page when the constructor is run... store it in a session variable.
Sorry I don't have any code examples at the time... but it's just another odd option you have, like variable variable functions ... (i.e. $c = 'count'; $NumOfEntries = $c($array);)`
mccann at cs dot usm dot maine dot edu
11-Jul-2003 10:38
`It is difficult to store objects in sessions as PHP doesn't necessarily have the correct class definitions on hand to unserialize the objects. Below is a simple session class that can act as a container for objects, but you have to pass the path to the class definition for this to work...
Assume you have this class defined in Session.php:
class Session
{
# attributes
var $_objects; # hash of named objects- of anything you want! Woot!
var $_classes; # hash of classes- This should import all classes required for objects in the session
var $_saved_objects;
function Session()
{
if (isset($_SESSION['__SESSSION_GLOBAL_OBJ']))
{$this=$_SESSION['__SESSSION_GLOBAL_OBJ'];}
else
{
$this->_objects=array();
$this->_classes=array();
$this->_saved_objects=array();
$_SESSION['__SESSSION_GLOBAL_OBJ']=$this;
}
}
function setObject($name,&$object/*, Required Class Paths */)
{
for ($i=2;$i<func_num_args();$i++)
{
if (!in_array(func_get_arg($i),$this->_classes))
{$this->_classes[]=func_get_arg($i);}
}
$this->_objects[$name]=&$object;
}
function getObject($name)
{
if (isset($this->_objects[$name]))
{return $this->_objects[$name];}
return false;
}
function __sleep()
{
# Serialize all objects
$keys = array_keys($this->_objects);
for ($i=0;$i<count($keys);$i++)
{$this->_saved_objects[$keys[$i]] = serialize($this->_objects[$keys[$i]]);}
return array("_saved_forms","_saved_objects","_classes");
}
function __wakeup()
{
# include all classes needed to unserialize objects in this session
for ($i=0;$i<count($this->_classes);$i++)
{include_once($this->_classes[$i]);}
# unserialize objects
$keys = array_keys($this->_saved_objects);
for ($i=0;$i<count($keys);$i++)
{
$this->_objects[$keys[$i]] = unserialize($this->_saved_objects[$keys[$i]]);
unset($this->_saved_objects[$keys[$i]]);
}
}
}
session_start();
if (!isset($_SESSION['__SESSSION_GLOBAL_OBJ']))
{$_SESSION['__SESSSION_GLOBAL_OBJ'] = new MSSession();}
$SESSION = &$_SESSION['__SESSSION_GLOBAL_OBJ'];
=========================================================
Now assume you have another class called MyClass defined in MyClass.php.... you can store it in the session as such:
include_once('Session.php');
include_once('stuff/MyClass.php');
$joe = new MyClass(/*arguments*/);
$SESSION->setObject('joe',$joe,'stuff/MyClass.php');
=========================================================
On another page you can retrieve this object from the session...
include_once('Session.php');
$joe = &$SESSION->getObject('joe');
=========================================================
This works, but you HAVE to pass setObject the path of every class definition you need to use the object you're embedding.`
darrylkuhn at hotmail dot com
11-May-2003 08:04
`This is pretty obvious, but as a note the __wakeup method cannot be used to require in the definition of the class for deserialization (although it would be nice... perhaps in future versions of php serialization might store the __wakeup method when an object is serialized to accomplish this).`
adamh at densi dot com
17-Apr-2003 10:46
`Correction to the above:
If you want to make sure all variables in your class are serialized, don't write a __sleep() function.`
jan at sorgalla dot com
07-Apr-2003 09:31
`If you want to ensure that all object vars are saved completely, try this:
<?php
class Foo
{
function __sleep() {
$objectVars = get_object_vars($this);
$serializeVars = array();
foreach ($objectVars as $key => $val) {
$serializeVars[] = $sKey;
}
return $serializeVars;
}
}
?>`
rkelly at NO dot whitley dot unimelb dot SPAM dot edu dot au
29-Jan-2003 09:56
`The documentation above says this function is 'supposed' to return an array with the names of variables to be saved. What this in reality means is that if you dont, bad things will happen.
I had forgotten to return the requested array after using __sleep to shutdown LDAP connections in an object, and was attempting to save the object as part of a session.
Since __sleep was not returning anything, the serialisation was evidently not returning anything either. This broke the stored session data, as one of the fields was completely missing and the unserialize parsing then failed. Only by hacking through the serialised session data by hand was I able to track down the error, and my silly mistake.
Perhaps PHP should have some way of dealing with this eventuality (treat it like an empty array?) so that it doesnt break sessions...?
Anyway, hopefully this might save a few people the hours of headache I just went through. Make sure you return something from this function!`
michael_muir at dstoutput dot com
07-Oct-2002 12:21
`The description isn't particularly clear about this, but it appears that if any variables identified in the array returned by __sleep() are objects, __sleep() will in turn be called on those objects. This is particularly useful if you have many levels of subordinate objects (not subclasses) stored in (for example) arrays. Simply return the array name from the 'top level' object's __sleep() and define a __sleep() for the object's class within the subordinate arrays and it shall be called for each.`
scott at graphictype dot com
01-Aug-2001 11:33
`Here is a sample class and some test statements to demonstrate how __sleep() is used.
If you do not return anything from __sleep(), your object will *not* be serialized. You must return something from __sleep() to tell serialize what to serialize.
<?
// to test the class
$x = new Scott();
print_r($x);
$y = serialize($x);
$z = unserialize($y);
print_r($z);
// Simple class to test __sleep()
class Scott {
// class variables
var $error;
var $svar = array();
// constructor
function Scott() {
$this->svar['Hello'] = "World";
}
function __sleep() {
$this->svar['Hello'] = "Yawn";
// return list of instance-variables to be serialized
return array('error', 'svar');
}
function __wakeup() {
$this->svar['test'] = "I'm here!";
}
}// end class
?>`
agland at squiz dot net
25-Jun-2001 10:38
`echoing output (even debugging statements) seems to cause problems in the __sleep() magic function. I suspect this is because, in the case of sessions, PHP is saving the session information (and running __sleep() in your object) after all the output has theoretically all been sent.
This resulted in the serialized object appearing as an empty string in our session files.`
add a note
References inside the constructor Serializing objects - objects in sessions

Last updated: Fri, 26 Jan 2007
show source | credits | stats | sitemap | contact | advertising | mirror sites
Copyright © 2001-2007 The PHP Group
All rights reserved.
This mirror generously provided by: Yahoo! Inc.
Last updated: Sat Mar 10 09:32:46 2007 PST