search for in the  
<PatternsFinal Keyword>
Last updated: Thu, 19 May 2005

Magic Methods

The function names __construct, __destruct (see Constructors and Destructors), __call, __get, __set (see Overloading), __sleep, __wakeup, and __toString are magical in PHP classes. You cannot have functions with these names in any of your classes unless you want the magic functionality associated with them.

Caution

PHP reserves all function names starting with __ as magical. It is recommended that you do not use function names with __ in PHP unless you want some documented magic functionality.

__sleep and __wakeup

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.

The intended use of __sleep is to close any database connections that the object may have, 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.

__toString

The __toString method allows a class to decide how it will react when it is converted to a string.

Example 19-25. Simple example

<?php
// Declare a simple class
class 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 the __toString method will only be called when it is directly combined with echo() or print().

Example 19-26. Cases where __toString is called

<?php
// __toString called
echo $class;

// __toString called (still a normal parameter for echo)
echo 'text', $class;

// __toString not called (concatenation operator used first)
echo 'text' . $class;

// __toString not called (cast to string first)
echo (string) $class;

// __toString not called (cast to string first)
echo "text $class";
?>


User Contributed Notes
Magic Methods
13-Apr-2005 08:17
I think __autoload und __clone are also magic methods. This should be extended in the first note on this page.
elias
11-Apr-2005 12:48
The default toString output is very useful for visual debuggin
because it shows the object id.
There is no function to resolve the id directly(?), but you
can do this:

<?php
function __toString()
{
  
sscanf((string)$this, "Object id #%d", $id);
   return
"Object(Template) id #$id";
}
?>

HTH,
elias
Gedoon-S
08-Apr-2005 02:26
I just thought it was worth mentioning that __toString works also with <?= $class ?>. It calls __toString and echoes what was returned just like <?php echo $class; ?> does, but it's shorter.
ddavenport at newagedigital dot com
27-Jan-2005 02:09
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.

Consider the following...

<?php
class SomeStupidStorageClass
{
  public function
getContents($pos, $len) { ...stuff... }
}

class
CryptedStorageClass extends SomeStupidStorageClass
{
  private
$decrypted_block;
  public function
getContents($pos, $len) { ...decrypt... }
}
?>

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....

<?php

class BetterClass
{
  private
$content;

  public function
__sleep()
  {
   return array(
'basedata1', 'basedata2');
  }

  public function
getContents() { ...stuff... }
}

class
BetterDerivedClass extends BetterClass
{
  private
$decrypted_block;

  public function
__sleep()
  {
   return
parent::__sleep();
  }

  public function
getContents() { ...decrypt... }
}

?>

The derived class has better control over its data, and we don't have to worry about something being stored that shouldn't be.
krisj1010 at gmail.com
09-Jan-2005 03:09
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.

So here is the work around:
<?php
public function __sleep()
{
 ...
code ...
$sleepVars    = array_keys((array)$this);
return
$sleepVars;
}
?>

Even though array_keys includes more information about the variable names than just the variable names -- it still seems to work appropriately.

<PatternsFinal Keyword>
 Last updated: Thu, 19 May 2005
Copyright © 2001-2005 The PHP Group
All rights reserved.
This unofficial mirror is operated at: The Server Pages
Last updated: Thu May 19 18:35:34 2005 EDT