5 min read

In this article by Jani Hartikainen, we’ll look at PHP’s “magic” features:

Magic methods, which are class methods with specific names, are used to perform various specialized tasks. They are grouped into two: overloading methods and non-overloading methods. Overloading magic methods are used when your code attempts to access a method or a property which does not exist. Non-overloading methods perform other tasks.

Magic functions, which are similar to magic methods, but are just plain functions outside any class. Currently there is only one magic function in PHP.

Magic constants, which are similar to constants in notation, but act more like “dynamic” constants – their value depends on where you use them.

We’ll also look at some practical examples of using some of these, and lastly we’ll check out what new features PHP 5.3 is going to add.

Magic methods

For starters, let’s take a look at the magic methods PHP provides. We will first go over the non-overloading methods.

__construct and __destruct

class SomeClass { 
public function __construct() {
}

public function __destruct() {
}
}

The most common magic method in PHP is __construct. In fact, you might not even have thought of it as a magic method at all, as it’s so common.  __construct is the class constructor method, which gets called when you instantiate a new object using the new keyword, and any parameters used will get passed to __construct.

$obj = new SomeClass();

__destruct is __construct’s “pair”. It is a class destructor, which is rarely used in PHP, but still it is good to know about  its existence. It gets called when your object falls out of scope or is garbage collected.

function someFunc() { 
$obj = new SomeClass();
//when the function ends, $obj falls out of scope and SomeClass __destruct is called
}
someFunc();

If you make the constructor private or protected, it means that the class cannot be instantiated, except inside a method of the same class. You can use this to your advantage, for example to create a singleton.

__clone

class SomeClass {
public $someValue;
public function __clone() {
$clone = new SomeClass();
$clone->someValue = $this->someValue;
return $clone;
}
}

The __clone method is called when you use PHP’s clone keyword, and is used to create a clone of the object. The purpose is that by implementing __clone, you can define a way to copy objects.

$obj1 = new SomeClass();
$obj1->someValue = 1;

$obj2 = clone $obj1;
echo $obj2->someValue;
//echos 1

Important: __clone is not the same as =. If you use = to assign an object to another variable, the other variable will still refer to the same object as the first one! If you use the clone keyword, the purpose is to return a new object with similar state as the original. Consider the following:

$obj1 = new SomeClass();
$obj1->someValue = 1;

$obj2 = $obj1;
$obj3 = clone $obj1;

$obj1->someValue = 2;

What are the values of the someValue property in $obj2 and $obj3 now? As we have used the assign operator to create $obj2, it refers to the same object as $obj1, thus $obj2->someValue is 2. When creating $obj3, we have used the clone keyword, so the __clone method was called. As __clone creates a new instance, $obj3->someValue is still the same as it was when we cloned $obj1: 1.

If you want to disable cloning, you can make __clone private or protected.

__toString

class SomeClass {
public function __toString() {
return 'someclass';
}
}

The __toString method is called when PHP needs to convert class instances into strings, for example when echoing:

$obj = new SomeClass();
echo $obj;
//will output 'someclass'

This can be a useful example to help you identify objects or when creating lists. If we have a user object, we could define a __toString method which outputs the user’s first and last names, and when we want to create a list of users, we could simply echo the objects themselves.

__sleep and __wakeup

class SomeClass {
private $_someVar;
public function __sleep() {
return array('_someVar');
}

public function __wakeup() {
}
}

These two methods are used with PHP’s serializer: __sleep is called with serialize(), __wakeup is called with unserialize(). Note that you will need to return an array of the class variables you want to save from __sleep. That’s why the example class returns an array with _someVar in it: Without it, the variable will not get serialized.

$obj = new SomeClass();
$serialized = serialize($obj);
//__sleep was called

unserialize($serialized);
//__wakeup was called

You typically won’t need to implement __sleep and __wakeup, as the default implementation will serialize classes correctly. However, in some special cases it can be useful. For example, if your class stores a reference to a PDO object, you will need to implement __sleep, as PDO objects cannot be serialized.

As with most other methods, you can make __sleep private or protected to stop serialization. Alternatively, you can throw an exception, which may be a better idea as you can provide a more meaningful error message.

An alternative to __sleep and __wakeup is the Serializable interface. However, as its behavior is different from these two methods, the interface is outside the scope of this article. You can find info on it in the PHP manual.

__set_state

class SomeClass {
public $someVar;

public static function __set_state($state) {
$obj = new SomeClass();
$obj->someVar = $state['someVar'];
return $obj;
}
}

This method is called in code created by var_export. It gets an array as its parameter, which contains a key and value for each of the class variables, and it must return an instance of the class.

$obj = new SomeClass();
$obj->someVar = 'my value';
var_export($obj);

This code will output something along the lines of:

SomeClass::__set_state(array('someVar'=>'my value'));

Note that var_export will also export private and protected variables of the class, so they too will be in the array.


Subscribe to the weekly Packt Hub newsletter

* indicates required

LEAVE A REPLY

Please enter your comment!
Please enter your name here