serialize() checks if your class has a function with
the magic name __sleep(). If so, that function is
executed 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.
If the method doesn't return anything then NULL is serialized and
E_NOTICE is issued.

Note:

It is not possible for __sleep() to return names of
private properties in parent classes. Doing this will result in an
E_NOTICE level error. Instead you may use the
Serializable interface.

The intended use of __sleep() is to commit pending
data or perform similar cleanup tasks. Also, the function is
useful if you have very large objects which do not need to 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 the 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.

The __toString() method allows a class to decide
how it will react when it is treated like a string. For example,
what echo $obj; will print. This method must
return a string, as otherwise a fatal E_RECOVERABLE_ERROR
level error is emitted.

Warning

You cannot throw an exception from within a
__toString() method. Doing so will
result in a fatal error.

Example #2 Simple example

<?php// Declare a simple classclass TestClass{ public $foo;

public function __construct($foo) {$this->foo = $foo; }

public function __toString() { return $this->foo; }}

$class = new TestClass('Hello');echo $class;?>

The above example will output:

Hello

It is worth noting that before PHP 5.2.0 the __toString()
method was only called when it was directly combined with
echo or print.
Since PHP 5.2.0, it is called in any string context (e.g. in
printf() with %s modifier) but not
in other types contexts (e.g. with %d modifier).
Since PHP 5.2.0, converting objects without __toString()
method to string would cause E_RECOVERABLE_ERROR.

Note:
When exporting an object, var_export() does not check
whether __set_state() is
implemented by the object's class, so re-importing such objects will fail,
if __set_state() is not implemented. Particularly, this affects some
internal classes.
It is the responsibility of the programmer to verify that only objects will
be re-imported, whose class implements __set_state().

This method is called by var_dump() when dumping an
object to get the properties that should be shown. If the method isn't
defined on an object, then all public, protected and private properties
will be shown.

User Contributed Notes 46 notes

The __toString() method is extremely useful for converting class attribute names and values into common string representations of data (of which there are many choices). I mention this as previous references to __toString() refer only to debugging uses.

C++-style operator overloading finally makes an appearance with the introduction to __invoke(). Unfortunately, with just '()'. In that sense, it is no more useful than having a default class method (probably quite useful actually) and not having to type out an entire method name. Complimenting wbcarts at juno dot com's point class below, the following allows calculating distance between one or more graph points...

Be very careful to define __set_state() in classes which inherit from a parent using it, as the static __set_state() call will be called for any children. If you are not careful, you will end up with an object of the wrong type. Here is an example:

Remember that setters and getters (__set, __get) will work in your class as long as you NOT SET the property with given name.

If you still want to have the public property definition in the class source code (phpDocumentor, editor code completition, or any other reason) when using these magic methods, simply unset() your public properties inside the constructor.__set/__get function will be called and code reader will see at first sight, which public properties are available.

When you use sessions, its very important to keep the sessiondata small, due to low performance with unserialize. Every class shoud extend from this class. The result will be, that no null Values are written to the sessiondata. It will increase performance.

If you are attempting to write an abstract/base class which automates the __sleep process in PHP5 you will run into some trouble if the subclasses which are being serialized have private/protected variables you need to be serialized.

The reason is, even though get_class($this) within the base class will return the subclass -- get_class_vars(get_class($this)) will *not* return the subclass' protected/private variables. Which makes sense -- using OO principles.

However, when automating __sleep it becomes necissary to have access to the private/protected subclass variables because their names have to be returned by __sleep.

Well now you can! This trick allows you to throw any type of exception from within a __toString(), with a full & correct backtrace.

How does it work? Well PHP __toString() handling is not as strict in every case: throwing an Exception from __toString() triggers a fatal E_ERROR, but returning a non-string value from a __toString() triggers a non-fatal E_RECOVERABLE_ERROR. Add a little bookkeeping, and can circumvented this PHP deficiency!(tested to work PHP 5.3+)

public static function errorHandler($errorNumber, $errorMessage, $errorFile, $errorLine) { if (isset(self::$_toStringException)) {$exception = self::$_toStringException;// Always unset '_toStringException', we don't want a straggler to be found later if something came between the setting and the errorself::$_toStringException = null; if (preg_match('~^Method .*::__toString\(\) must return a string value$~', $errorMessage)) throw $exception; } return false; }

public static function throwToStringException($exception) {// Should not occur with prescribed usage, but in case of recursion: clean out exception, return a valid string, and weepif (isset(self::$_toStringException)) {self::$_toStringException = null; return ''; }

Intriguing what happens when __sleep() and __wakeup() and sessions() are mixed. I had a hunch that, as session data is serialized, __sleep would be called when an object, or whatever, is stored in _SESSION. true. The same hunch applied when session_start() was called. Would __wakeup() be called? True. Very helpful, specifically as I'm building massive objects (well, lots of simple objects stored in sessions), and need lots of automated tasks (potentially) reloaded at "wakeup" time. (for instance, restarting a database session/connection).

One of the principles of OOP is encapsulation--the idea that an object should handle its own data and no others'. Asking base classes to take care of subclasses' data, esp considering that a class can't possibly know how many dozens of ways it will be extended, is irresponsible and dangerous.

If SomeStupidStorageClass decided to serialize its subclasses' data as well as its own, a portion of what was once an encrypted thingie could be stored, in the clear, wherever the thingie was stored. Obviously, CryptedStorageClass would never have chosen this...but it had to either know how to serialize its parent class's data without calling parent::_sleep(), or let the base class do what it wanted to.

Considering encapsulation again, no class should have to know how the parent handles its own private data. And it certainly shouldn't have to worry that users will find a way to break access controls in the name of convenience.

If a class wants both to have private/protected data and to survive serialization, it should have its own __sleep() method which asks the parent to report its own fields and then adds to the list if applicable. Like so....

The above hint for using array_keys((array)$obj) got me investigating how to get __sleep to really work with object hierarchies.

With PHP 5.2.3, If you want to serialize an object that is part of an object hierarchy and you want to selectively serialize members (public, private, and protected) by manually specifying the array of members, there are a few simple rules for naming members that you must follow:

1. public members should be named using just their member name, like so:

<?phpclass Foo { public $bar;

public function __sleep() { return array("bar"); }}?>

2. protected members should be named using "\0" . "*" . "\0" . member name, like so:

<?phpclass Foo { protected $bar;

public function __sleep() { return array("\0*\0bar"); }}?>

3. private members should be named using "\0" . class name . "\0" . member name, like so:

<?phpclass Foo { private $bar;

public function __sleep() { return array("\0Foo\0bar"); }}?>

So with this information let us serialize a class hierarchy correctly:

Now if you comment out all of the __sleep() functions and output the serialized string, you will see that the output doesn't change. The most important part of course is that with the proper __sleep() functions, we can unserialize the string and get a properly set up object.

I hope this solves the mystery for everybody. __sleep() does work, if you use it correctly :-)

I have been trying to test the __debugInfo but no luck. I am running php 5.6.5 on MAC OSX Yosemite and tried even the example above but nothing seems to be called. When calling var_dump on an object it doesn't trigger the __debugInfo magic method. Any Idea ?

In recent versions of PHP, if you define __toString with arguments it will trigger a Fatal error: "__tostring() cannot take arguments". But, if you really need this (like I needed, because my framework heavily used these arguments), you have a workaround:<?phpclass a { public function __toString() { list($a) = func_get_args(); return $a; }}

I've just come accross something interesting relating to storing PHP5 objects in a session. If you don't provide an __autoload(), then you MUST load the class definition before calling session_start(). I guess that when you call session_start(), any objects in the session are unserialized then and there and placed into $_SESSION. If you don't provide the class definition before calling session_start(), your object will get the class __PHP_Incomplete_Class, and you won't be able to use it for anything.

Fatal error: The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "MyClass" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition.

Hopefully in some future release of PHP, __PHP_Incomplete_Class will be smart enough to check for a class definition at time of use (method call or property operation), and, if the class exists, magically "complete" itself and turn into the desired object.

When overriding __get and __set, the above code can work (as expected) but it depends on your __get implementation rather than your __set. In fact, __set is never called with the above code. It appears that PHP (at least as of 5.1) uses a reference to whatever was returned by __get. To be more verbose, the above code is essentially identical to:

You could just as easily add an addMixin() method that would allow you to add multiple objects to an array, and then iterate over that array until you found the right method. As noted, these are referred to as a Mixins in other languages.

/** * The API is flat and has ~ 150 endpoints, all of which take optional parameters * from up to 3 groups (method params, authentication, filters). Instead of * implementing the interface and adding countless stubs that have basically * the same signature, i just map its methods here and use __call(). */private function mapApiMethods(){$reflectionClass = new ReflectionClass(SomeApiInterface::class);

Another small thing that is important to note about __sleep() and privte member variables:

<?phpclass A{ private $a;

public function __construct() {$this->a = 1; }}

class B extends A{ protected $b;

public function __construct() {parent::__construct();$this->b = 2; }

function __sleep() { return array('a', 'b'); }}

serialize(new B);?>

result:Notice: serialize(): "a" returned as member variable from __sleep() but does not exist in ...

To summerize: in a given class hierarchy in which parent classes contain private member variables, those variables are serialized when __sleep() is not defined. However, once __sleep() is defined, there is no way to make those private member variables serialized as well. From that point on, serialization is performed from the visibility scope of the subclass.

It is particularly important to note this little quirk when designing base classes that their derivables may be serialized, or when subclassing an external library class.

Properties that are Arrays: attempting to set array values like "$a->test_array[] = 'asdf';" from outside this object will result in an "Indirect modification of overloaded property" notice and the operation completely ignored. You can't use '[]' for array value assignment in this context (with the exception only if you made __get() return by reference, in which case, it would work fine and bypass the __set() method altogether). You can work around this doing something like unioning the array instead:

Properties that are Objects: as long as you have that __get() method, you can freely access and alter that sub object's own properties, bypassing __set() entirely. Remember, objects are assigned and passed by reference naturally.

<?php

$a->test_obj->prop = 1; // fine if $a did not have a set method declared.

Serializing objects is problematic with references. This is solved redefining the __sleep() magic method. This is also problematic when parent class has private variables since the parent object is not accessible nor its private variables from within the child object.

I found a solution that seems working for classes that implements this __sleep() method, and for its subclasses. Without more work in subclasses. The inheritance system does the trick.

Recursively __sleep() call parent' __sleep() and return the whole array of variables of the object instance to be serialized.

<?phpclass foo {}

class a { private $var1;

function __construct(foo &$obj = NULL) {$this->var1 = &$obj; }

/** Return its variables array, if its parent exists and the __sleep method is accessible, call it and push the result into the array and return the whole thing. */public function __sleep() {$a = array_keys(get_object_vars(&$this)); if (method_exists(parent, '__sleep')) {$p = parent::__sleep();array_push($a, $p); }; return $a; }}

this way subcore is being serialized by core when core is being serialized. subcore handles its own data and core stores it as a serialize string inside itself. on wakeup core unserializes subcore.

this may have a performance cost, but if you have many objects connected this way this is the best way of serializing them. you only need to serialize the the main object wich will serialize all those below which will serialize all those below them again. in effect causing a sort of chainreaction in wich each object takes care of its own info.

offcoarse you always need to store the eventualy serialized string in a safe place. somebody got experience with this way of __wakeup and __sleep.

Reason: $b is unserialized before $name. By the time B::__wakeup is called, $a->name does not yet have a value.

So be aware that the order in which your class variables are defined is important! You need to manually order them by dependencies - or write a __sleep function and order them by depencies there. (Currently I can't tell which option I hate more)

It's because PHP have bug in parsing syntax (a lot of).Just make it easier to parse and it would work.For example, like this:<?php$c = $b->a;$c();?>

Or this, if you use 5.4 (if you using 5.3 just move call function to the each class which need it or to some base abstract class):<?phptrait TInnerClosuresInvoker { function __call($method, $args) { if (isset($this->$method) && is_callable($method)) {$closure = $this->$method;call_user_func_array($closure, $args); } else {trigger_error('Call to undefined method '.__CLASS__.'::'.$method.'()', E_USER_ERROR); } }}class A { use TInnerClosuresInvoker; ...}?>

You don't need to serialize the class default values, only those which have changed. It might be important for large objects. Note the example below, for simplicity, always serializes arrays and objects.

<?phpclass MyBaseClass { public $name='object'; // these are default class valuespublic $test=1; public $test2; // equals to NULL in fact

public function __construct(){$this->test2='some text'; // this is not a default value, although called in the constructor}

This means that if you have a pseudo-temporary object that contains a class to auto revert to, you have to revert that session object in the initialization of the website rather than via a __wakeup() script.

__sleep() handles protected/private properties very well. You should never rely on get_class_vars() to retrieve property names since this function only returns the public properties. Use the Reflection API instead for that purpose. Better yet, if you know which ones you want to save it is always faster to specify the return array manually.

There is no automatic way I have found aside from some internal state check to verify a class. It will always return an object. The only way around that is to force it out to string either where I did, or $ret = (string) new Test(); then test the bool of your output..

if (!$ret) { echo "noooo!"; }

But now you have no calling methods, so I hope you passed some data in to get a usable string out.

Of course, if your class isn't named test, you can add a method..

public function test() { return $this->state;}

Logically that will work regardless of the _toString(), but I had hoped to post this to help others see that there are a multitude of ways to check the validity of a class once it is loaded. In __construct you can add any number of checks and set your state appropriately.