⌂ Home ▲ Previous: Classe members ▼ Next: Constructors and destructors
Magic methods are special methods which override PHP’s default’s action when certain actions are performed on an object.
Caution
All methods names starting with __ are reserved by PHP. Therefore, it is not recommended to use such method names unless overriding PHP’s behavior.
The following method names are considered magical: __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __serialize(), __unserialize(), __toString(), __invoke(), __set_state(), __clone(), and __debugInfo().
Warning
All magic methods, with the exception of __construct(), __destruct(), and __clone(), must be declared as public, otherwise an E_WARNING is emitted. Prior to PHP 8.0.0, no diagnostic was emitted for the magic methods __sleep(), __wakeup(), __serialize(), __unserialize(), and __set_state().
Warning
If type declarations are used in the definition of a magic method, they must be identical to the signature described in this document. Otherwise, a fatal error is emitted. Prior to PHP 8.0.0, no diagnostic was emitted. However, __construct() and __destruct() must not declare a return type; otherwise a fatal error is emitted.
__set, __get, __isset, __unsetpublic __set(string $name, mixed $value): void
public __get(string $name): mixed
public __isset(string $name): bool
public __unset(string $name): void
__set() is run when writing data to inaccessible (protected or private) or non-existing properties.
__get() is utilized for reading data from inaccessible (protected or private) or non-existing properties.
__isset() is triggered by calling isset() or empty() on inaccessible (protected or private) or non-existing properties.
__unset() is invoked when unset() is used on inaccessible (protected or private) or non-existing properties.
The $name argument is the name of the property being interacted with. The __set() method’s $value argument specifies the value the $name‘ed property should be set to.
Property overloading only works in object context. These magic methods will not be triggered in static context. Therefore these methods should not be declared static. A warning is issued if one of the magic overloading methods is declared static.
Note:
The return value of __set() is ignored because of the way PHP processes the assignment operator. Similarly, __get() is never called when chaining assignments together like this:
$a = $obj->b = 8;
Note:
PHP will not call an overloaded method from within the same overloaded method. That means, for example, writing return $this->foo inside of __get() will return null and raise an E_WARNING if there is no foo property defined, rather than calling __get() a second time. However, overload methods may invoke other overload methods implicitly (such as __set() triggering __get()).
Example: Overloading properties via the __get(), __set(), __isset() and __unset() methods
<?php
class PropertyTest
{
/** Location for overloaded data. */
private $data = array();
/** Overloading not used on declared properties. */
public $declared = 1;
/** Overloading only used on this when accessed outside the class. */
private $hidden = 2;
public function __set($name, $value)
{
echo "Setting '$name' to '$value'\n";
$this->data[$name] = $value;
}
public function __get($name)
{
echo "Getting '$name'\n";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
$trace = debug_backtrace();
trigger_error(
'Undefined property via __get(): ' . $name .
' in ' . $trace[0]['file'] .
' on line ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
public function __isset($name)
{
echo "Is '$name' set?\n";
return isset($this->data[$name]);
}
public function __unset($name)
{
echo "Unsetting '$name'\n";
unset($this->data[$name]);
}
/** Not a magic method, just here for example. */
public function getHidden()
{
return $this->hidden;
}
}
$obj = new PropertyTest;
$obj->a = 1;
echo $obj->a . "\n\n";
var_dump(isset($obj->a));
unset($obj->a);
var_dump(isset($obj->a));
echo "\n";
echo $obj->declared . "\n\n";
echo "Let's experiment with the private property named 'hidden':\n";
echo "Privates are visible inside the class, so __get() not used...\n";
echo $obj->getHidden() . "\n";
echo "Privates not visible outside of class, so __get() is used...\n";
echo $obj->hidden . "\n";
?>
The above example will output:
Setting 'a' to '1'
Getting 'a'
1
Is 'a' set?
bool(true)
Unsetting 'a'
Is 'a' set?
bool(false)
1
Let's experiment with the private property named 'hidden':
Privates are visible inside the class, so __get() not used...
2
Privates not visible outside of class, so __get() is used...
Getting 'hidden'
Notice: Undefined property via __get(): hidden in <file> on line 70 in <file> on line 29
__set__set is run when writing data to inaccessible (protected or private) or non-existing properties
public __set(string $name, mixed $value): void
Example: __set magic method
<?php
class SomeClass
{
private array $data = [];
public function __set(string $propertyName, mixed $propertyValue): void
{
print(
"Magic method __set\n\n"
. "Argument name: {$propertyName}\n"
. "Argument value: {$propertyValue}\n\n"
);
$this->data[$propertyName] = $propertyValue;
}
}
$someObject = new SomeClass();
$someObject->variable = "hello";
var_dump($someObject);
print(PHP_EOL);
Result (PHP 8.4):
Magic method __set
Argument name: variable
Argument value: hello
object(SomeClass)#1 (1) {
["data":"SomeClass":private]=>
array(1) {
["variable"]=>
string(5) "hello"
}
}
Source code: Example
__get__get() is utilized for reading data from inaccessible (protected or private) or non-existing properties.
public __set(string $name, mixed $value): void
Example: __get magic method
<?php
class SomeClass
{
private array $data = [
'platform' => 'linux',
'language' => 'php',
'database' => 'postgresql'
];
public function __get(string $propertyName): mixed
{
print(
"Magic method __get\n\n"
. "Argument name: {$propertyName}\n\n"
);
if (! isset($this->data[$propertyName])) {
return null;
}
return $this->data[$propertyName];
}
}
$someObject = new SomeClass();
var_dump($someObject);
print(PHP_EOL);
print($someObject->platform . PHP_EOL . PHP_EOL);
Result (PHP 8.4):
object(SomeClass)#1 (1) {
["data":"SomeClass":private]=>
array(3) {
["platform"]=>
string(5) "linux"
["language"]=>
string(3) "php"
["database"]=>
string(10) "postgresql"
}
}
Magic method __get
Argument name: platform
linux
Source code: Example
__isset__isset() is triggered by calling isset() or empty() on inaccessible (protected or private) or non-existing properties.
public __isset(string $name): bool
Example: __isset magic method
<?php
class SomeClass
{
private array $data = [
'platform' => 'linux',
'language' => 'php',
'database' => 'postgresql'
];
public function __isset(string $propertyName): bool
{
print(
"Magic method __isset\n\n"
. "Property name: $propertyName\n\n"
);
return isset($this->data[$propertyName]);
}
}
$someObject = new SomeClass();
var_dump($someObject);
print(PHP_EOL);
print(var_export(isset($someObject->platform), true) . PHP_EOL . PHP_EOL);
print(var_export(isset($someObject->unexistent), true) . PHP_EOL . PHP_EOL);
Result (PHP 8.4):
object(SomeClass)#1 (1) {
["data":"SomeClass":private]=>
array(3) {
["platform"]=>
string(5) "linux"
["language"]=>
string(3) "php"
["database"]=>
string(10) "postgresql"
}
}
Magic method __isset
Property name: platform
true
Magic method __isset
Property name: unexistent
false
Source code: Example
__unsetpublic __unset(string $name): void
__unset() is invoked when unset() is used on inaccessible (protected or private) or non-existing properties.
Example: __unset magic method
<?php
class SomeClass
{
private array $data = [
'platform' => 'linux',
'language' => 'php',
'database' => 'postgresql'
];
public function __unset(string $propertyName): void
{
print(
"Magic method __unset\n\n"
. "Property name: $propertyName\n\n"
);
unset($this->data[$propertyName]);
}
}
$someObject = new SomeClass();
var_dump($someObject);
print(PHP_EOL);
unset($someObject->platform);
var_dump($someObject);
print(PHP_EOL);
Result (PHP 8.4):
object(SomeClass)#1 (1) {
["data":"SomeClass":private]=>
array(3) {
["platform"]=>
string(5) "linux"
["language"]=>
string(3) "php"
["database"]=>
string(10) "postgresql"
}
}
Magic method __unset
Property name: platform
object(SomeClass)#1 (1) {
["data":"SomeClass":private]=>
array(2) {
["language"]=>
string(3) "php"
["database"]=>
string(10) "postgresql"
}
}
Source code: Example
__call and callStaticpublic __call(string $name, array $arguments): mixed
public static __callStatic(string $name, array $arguments): mixed
__call() is triggered when invoking inaccessible methods in an object context.
__callStatic() is triggered when invoking inaccessible methods in a static context.
The $name argument is the name of the method being called. The $arguments argument is an enumerated array containing the parameters passed to the $name‘ed method.
Example: Overloading methods via the __call() and __callStatic() methods
<?php
class MethodTest
{
public function __call($name, $arguments)
{
// Note: value of $name is case sensitive.
echo "Calling object method '$name' "
. implode(', ', $arguments). "\n";
}
public static function __callStatic($name, $arguments)
{
// Note: value of $name is case sensitive.
echo "Calling static method '$name' "
. implode(', ', $arguments). "\n";
}
}
$obj = new MethodTest;
$obj->runTest('in object context');
MethodTest::runTest('in static context');
?>
The above example will output:
Calling object method 'runTest' in object context
Calling static method 'runTest' in static context
__call__call() is triggered when invoking inaccessible methods in an object context.
public __call(string $name, array $arguments): mixed
Example: __call magic method
<?php
class SomeClass
{
private array $actions = [];
function __construct()
{
$this->actions = [
'adding' => function($values) {
return array_sum($values);
},
'multipling' => function($values) {
return array_product($values);
},
];
}
public function __call(string $methodName, mixed $methodArguments): mixed
{
print(
"Magic method __call\n\n"
. "Method name: {$methodName}\n\m"
. "Method arguments:\n"
);
var_dump($methodArguments);
print(PHP_EOL);
if (! isset($this->actions[$methodName])) {
return null;
}
return $this->actions[$methodName]($methodArguments);
}
}
$someObject = new SomeClass();
$result = $someObject->adding(1, 2, 3);
print($result . PHP_EOL . PHP_EOL);
Result (PHP 8.4):
Magic method __call
Method name: adding
Method arguments:
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
6
Source code: Example
__callStatic__callStatic() is triggered when invoking inaccessible methods in a static context.
public static __callStatic(string $name, array $arguments): mixed
Example: __callStatic magic method
<?php
class SomeClass
{
private const array ACTIONS = [
'adding' => 'array_sum',
'multipling' => 'array_product',
];
public static function __callStatic(string $methodName, mixed $methodArguments): mixed
{
print(
"Magic method __callStatic\n\n"
. "Method name: {$methodName}\n\n"
. "Method arguments:\n"
);
var_dump($methodArguments);
print(PHP_EOL);
if (! isset(static::ACTIONS[$methodName])) {
return null;
}
return static::ACTIONS[$methodName]($methodArguments);
}
}
$result = SomeClass::adding(1, 2, 3);
print($result . PHP_EOL . PHP_EOL);
Result (PHP 8.4):
Magic method __callStatic
Method name: adding
Method arguments:
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
6
Source code: Example
__invoke and __toString__invokeThe __invoke() method is called when a script tries to call an object as a function.
__invoke( ...$values): mixed
Example: Using __invoke()
<?php
class CallableClass
{
public function __invoke($x)
{
var_dump($x);
}
}
$obj = new CallableClass;
$obj(5);
var_dump(is_callable($obj));
?>
The above example will output:
int(5)
bool(true)
Example: Using __invoke()
<?php
class Sort
{
private $key;
public function __construct(string $key)
{
$this->key = $key;
}
public function __invoke(array $a, array $b): int
{
return $a[$this->key] <=> $b[$this->key];
}
}
$customers = [
['id' => 1, 'first_name' => 'John', 'last_name' => 'Do'],
['id' => 3, 'first_name' => 'Alice', 'last_name' => 'Gustav'],
['id' => 2, 'first_name' => 'Bob', 'last_name' => 'Filipe']
];
// sort customers by first name
usort($customers, new Sort('first_name'));
print_r($customers);
// sort customers by last name
usort($customers, new Sort('last_name'));
print_r($customers);
?>
The above example will output:
Array
(
[0] => Array
(
[id] => 3
[first_name] => Alice
[last_name] => Gustav
)
[1] => Array
(
[id] => 2
[first_name] => Bob
[last_name] => Filipe
)
[2] => Array
(
[id] => 1
[first_name] => John
[last_name] => Do
)
)
Array
(
[0] => Array
(
[id] => 1
[first_name] => John
[last_name] => Do
)
[1] => Array
(
[id] => 2
[first_name] => Bob
[last_name] => Filipe
)
[2] => Array
(
[id] => 3
[first_name] => Alice
[last_name] => Gustav
)
)
Example: __invoke magic method
<?php
class SomeClass
{
public function __invoke(...$callableArguments): int
{
print(
"Magic method __invoke\n\n"
. "Arguments of the callable:\n\n"
);
var_dump($callableArguments);
print(PHP_EOL);
foreach ($callableArguments as $argument) {
print(
'Argument type: ' . gettype($argument) . PHP_EOL
. 'Exported: ' . var_export($argument, true) . PHP_EOL
. PHP_EOL
);
}
return count($callableArguments);
}
}
$someObject = new SomeClass();
$result = $someObject(4, "hello", [2, 3]);
print($result . PHP_EOL . PHP_EOL);
Result (PHP 8.4):
Magic method __invoke
Arguments of the callable:
array(3) {
[0]=>
int(4)
[1]=>
string(5) "hello"
[2]=>
array(2) {
[0]=>
int(2)
[1]=>
int(3)
}
}
Argument type: integer
Exported: 4
Argument type: string
Exported: 'hello'
Argument type: array
Exported: array (
0 => 2,
1 => 3,
)
3
Source code: Example
__toStringThe __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.
public __toString(): string
Warning
As of PHP 8.0.0, the return value follows standard PHP type semantics, meaning it will be coerced into a string if possible and if strict typing is disabled.
A Stringable object will not be accepted by a string type declaration if strict typing is enabled. If such behaviour is wanted the type declaration must accept Stringable and string via a union type.
As of PHP 8.0.0, any class that contains a __toString() method will also implicitly implement the Stringable interface, and will thus pass type checks for that interface. Explicitly implementing the interface anyway is recommended.
In PHP 7.4, the returned value must be a string, otherwise an Error is thrown.
Prior to PHP 7.4.0, the returned value must be a string, otherwise a fatal E_RECOVERABLE_ERROR is emitted.
Warning
It was not possible to throw an exception from within a __toString() method prior to PHP 7.4.0. Doing so will result in a fatal error.
Example: 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
Example: __toString magic method
<?php
class SomeClass
{
private const string PREFIX = '<';
private const string POSTFIX = '>';
function __construct(private string $content = '')
{
}
public function __toString(): string
{
print(
"Magic method __toString\n\n"
);
return static::PREFIX . $this->content . static::POSTFIX;
}
}
$someObject = new SomeClass('Veni, vidi, vim!');
print($someObject . PHP_EOL . PHP_EOL);
Result (PHP 8.4):
Magic method __toString
<Veni, vidi, vim!>
Source code: Example
__sleep and __wakeuppublic __sleep(): array
public __wakeup(): void
serialize() checks if the 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. Use __serialize() instead.
Note:
As of PHP 8.0.0, returning a value which is not an array from __sleep() generates a warning. Previously, it generated a notice.
The intended use of __sleep() is to commit pending data or perform similar cleanup tasks. Also, the function is useful if a very large object doesn’t 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.
Example: Sleep and wakeup
<?php
class Connection
{
protected $link;
private $dsn, $username, $password;
public function __construct($dsn, $username, $password)
{
$this->dsn = $dsn;
$this->username = $username;
$this->password = $password;
$this->connect();
}
private function connect()
{
$this->link = new PDO($this->dsn, $this->username, $this->password);
}
public function __sleep()
{
return array('dsn', 'username', 'password');
}
public function __wakeup()
{
$this->connect();
}
}?>
__sleepserialize() checks if the 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.
public __sleep(): array
Example: __sleep magic method
<?php
class SomeClass
{
public function __construct(
public string $somePublicProperty = 'some public',
public string $otherPublicProperty = 'other public',
protected string $someProtectedProperty = 'some protected',
protected string $otherProtectedProperty = 'other protected',
private string $somePrivateProperty = 'some private',
private string $otherPrivateProperty = 'other private',
) {
}
public function __sleep(): array
{
print(
"Magic method __sleep\n\n"
);
return [
'somePublicProperty',
'someProtectedProperty',
'somePrivateProperty',
];
}
}
$someObject = new SomeClass();
var_dump($someObject);
print(PHP_EOL);
$result = serialize($someObject);
print($result . PHP_EOL . PHP_EOL);
$coresult = unserialize($result);
var_dump($coresult);
print(PHP_EOL);
Result (PHP 8.4):
object(SomeClass)#1 (6) {
["somePublicProperty"]=>
string(11) "some public"
["otherPublicProperty"]=>
string(12) "other public"
["someProtectedProperty":protected]=>
string(14) "some protected"
["otherProtectedProperty":protected]=>
string(15) "other protected"
["somePrivateProperty":"SomeClass":private]=>
string(12) "some private"
["otherPrivateProperty":"SomeClass":private]=>
string(13) "other private"
}
Magic method __sleep
O:9:"SomeClass":3:{s:18:"somePublicProperty";s:11:"some public";s:24:"*someProtectedProperty";s:14:"some protected";s:30:"SomeClasssomePrivateProperty";s:12:"some private";}
object(SomeClass)#2 (3) {
["somePublicProperty"]=>
string(11) "some public"
["otherPublicProperty"]=>
uninitialized(string)
["someProtectedProperty":protected]=>
string(14) "some protected"
["otherProtectedProperty":protected]=>
uninitialized(string)
["somePrivateProperty":"SomeClass":private]=>
string(12) "some private"
["otherPrivateProperty":"SomeClass":private]=>
uninitialized(string)
}
Source code: Example
__wakeupConversely, 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.
public __wakeup(): void
Example: __wakeup magic method
<?php
class SomeClass
{
private const string UNSERIALISATION_HIDDEN_FIELD_MESSAGE = 'hidden during unserialisation';
public function __construct(
public string $somePublicProperty = 'some public',
public string $otherPublicProperty = 'other public',
protected string $someProtectedProperty = 'some protected',
protected string $otherProtectedProperty = 'other protected',
private string $somePrivateProperty = 'some private',
private string $otherPrivateProperty = 'other private',
) {
}
public function __wakeup(): void
{
print(
"Magic method __wakeup\n\n"
);
$this->someProtectedProperty = static::UNSERIALISATION_HIDDEN_FIELD_MESSAGE;
$this->otherProtectedProperty = static::UNSERIALISATION_HIDDEN_FIELD_MESSAGE;
$this->somePrivateProperty = static::UNSERIALISATION_HIDDEN_FIELD_MESSAGE;
$this->otherPrivateProperty = static::UNSERIALISATION_HIDDEN_FIELD_MESSAGE;
}
}
$someObject = new SomeClass();
var_dump($someObject);
print(PHP_EOL);
$result = serialize($someObject);
print($result . PHP_EOL . PHP_EOL);
$coresult = unserialize($result);
var_dump($coresult);
print(PHP_EOL);
Result (PHP 8.4):
object(SomeClass)#1 (6) {
["somePublicProperty"]=>
string(11) "some public"
["otherPublicProperty"]=>
string(12) "other public"
["someProtectedProperty":protected]=>
string(14) "some protected"
["otherProtectedProperty":protected]=>
string(15) "other protected"
["somePrivateProperty":"SomeClass":private]=>
string(12) "some private"
["otherPrivateProperty":"SomeClass":private]=>
string(13) "other private"
}
O:9:"SomeClass":6:{s:18:"somePublicProperty";s:11:"some public";s:19:"otherPublicProperty";s:12:"other public";s:24:"*someProtectedProperty";s:14:"some protected";s:25:"*otherProtectedProperty";s:15:"other protected";s:30:"SomeClasssomePrivateProperty";s:12:"some private";s:31:"SomeClassotherPrivateProperty";s:13:"other private";}
Magic method __wakeup
object(SomeClass)#2 (6) {
["somePublicProperty"]=>
string(11) "some public"
["otherPublicProperty"]=>
string(12) "other public"
["someProtectedProperty":protected]=>
string(29) "hidden during unserialisation"
["otherProtectedProperty":protected]=>
string(29) "hidden during unserialisation"
["somePrivateProperty":"SomeClass":private]=>
string(29) "hidden during unserialisation"
["otherPrivateProperty":"SomeClass":private]=>
string(29) "hidden during unserialisation"
}
Source code: Example
__serialize() and __unserialize()public __serialize(): array
public __unserialize(array $data): void
serialize() checks if the class has a function with the magic name __serialize(). If so, that function is executed prior to any serialization. It must construct and return an associative array of key/value pairs that represent the serialized form of the object. If no array is returned a TypeError will be thrown.
Note:
If both __serialize() and __sleep() are defined in the same object, only __serialize() will be called. __sleep() will be ignored. If the object implements the Serializable interface, the interface’s serialize() method will be ignored and __serialize() used instead.
The intended use of __serialize() is to define a serialization-friendly arbitrary representation of the object. Elements of the array may correspond to properties of the object but that is not required.
Conversely, unserialize() checks for the presence of a function with the magic name __unserialize(). If present, this function will be passed the restored array that was returned from __serialize(). It may then restore the properties of the object from that array as appropriate.
Note:
If both __unserialize() and __wakeup() are defined in the same object, only __unserialize() will be called. __wakeup() will be ignored.
Note:
This feature is available as of PHP 7.4.0.
Example: Serialize and unserialize
<?php
class Connection
{
protected $link;
private $dsn, $username, $password;
public function __construct($dsn, $username, $password)
{
$this->dsn = $dsn;
$this->username = $username;
$this->password = $password;
$this->connect();
}
private function connect()
{
$this->link = new PDO($this->dsn, $this->username, $this->password);
}
public function __serialize(): array
{
return [
'dsn' => $this->dsn,
'user' => $this->username,
'pass' => $this->password,
];
}
public function __unserialize(array $data): void
{
$this->dsn = $data['dsn'];
$this->username = $data['user'];
$this->password = $data['pass'];
$this->connect();
}
}?>
__serializepublic __serialize(): array
serialize() checks if the class has a function with the magic name __serialize(). If so, that function is executed prior to any serialization. It must construct and return an associative array of key/value pairs that represent the serialized form of the object. If no array is returned a TypeError will be thrown.
Example: __serialize magic method
<?php
class SomeClass
{
public function __construct(
public string $somePublicProperty = 'some public',
public string $otherPublicProperty = 'other public',
protected string $someProtectedProperty = 'some protected',
protected string $otherProtectedProperty = 'other protected',
private string $somePrivateProperty = 'some private',
private string $otherPrivateProperty = 'other private',
) {
}
public function __serialize(): array
{
print(
"Magic method __serialize\n\n"
);
return [
'somePublicProperty' => $this->somePublicProperty,
'someProtectedProperty' => $this->someProtectedProperty,
'somePrivateProperty' => $this->somePrivateProperty,
];
}
}
$someObject = new SomeClass();
var_dump($someObject);
print(PHP_EOL);
$result = serialize($someObject);
print($result . PHP_EOL . PHP_EOL);
$coresult = unserialize($result);
var_dump($coresult);
print(PHP_EOL);
Result (PHP 8.4):
object(SomeClass)#1 (6) {
["somePublicProperty"]=>
string(11) "some public"
["otherPublicProperty"]=>
string(12) "other public"
["someProtectedProperty":protected]=>
string(14) "some protected"
["otherProtectedProperty":protected]=>
string(15) "other protected"
["somePrivateProperty":"SomeClass":private]=>
string(12) "some private"
["otherPrivateProperty":"SomeClass":private]=>
string(13) "other private"
}
Magic method __serialize
O:9:"SomeClass":3:{s:18:"somePublicProperty";s:11:"some public";s:21:"someProtectedProperty";s:14:"some protected";s:19:"somePrivateProperty";s:12:"some private";}
object(SomeClass)#2 (3) {
["somePublicProperty"]=>
string(11) "some public"
["otherPublicProperty"]=>
uninitialized(string)
["someProtectedProperty":protected]=>
string(14) "some protected"
["otherProtectedProperty":protected]=>
uninitialized(string)
["somePrivateProperty":"SomeClass":private]=>
string(12) "some private"
["otherPrivateProperty":"SomeClass":private]=>
uninitialized(string)
}
Source code: Example
__unserializepublic __unserialize(array $data): void
Conversely, unserialize() checks for the presence of a function with the magic name __unserialize(). If present, this function will be passed the restored array that was returned from __serialize(). It may then restore the properties of the object from that array as appropriate.
Example: __nuserialize magic method
<?php
class SomeClass
{
private const string UNSERIALISATION_HIDDEN_FIELD_MESSAGE = 'hidden during unserialisation';
public function __construct(
public string $somePublicProperty = 'some public',
public string $otherPublicProperty = 'other public',
protected string $someProtectedProperty = 'some protected',
protected string $otherProtectedProperty = 'other protected',
private string $somePrivateProperty = 'some private',
private string $otherPrivateProperty = 'other private',
) {
}
public function __unserialize(array $data): void
{
print(
"Magic method __unserialize\n\n"
. "Data:\n"
);
var_dump($data);
print(PHP_EOL);
$this->somePublicProperty = $data['somePublicProperty'];
$this->otherPublicProperty = $data['otherPublicProperty'];
$this->someProtectedProperty = static::UNSERIALISATION_HIDDEN_FIELD_MESSAGE;
$this->otherProtectedProperty = static::UNSERIALISATION_HIDDEN_FIELD_MESSAGE;
$this->somePrivateProperty = static::UNSERIALISATION_HIDDEN_FIELD_MESSAGE;
$this->otherPrivateProperty = static::UNSERIALISATION_HIDDEN_FIELD_MESSAGE;
}
}
$someObject = new SomeClass();
var_dump($someObject);
print(PHP_EOL);
$result = serialize($someObject);
print($result . PHP_EOL . PHP_EOL);
$coresult = unserialize($result);
var_dump($coresult);
print(PHP_EOL);
Result (PHP 8.4):
object(SomeClass)#1 (6) {
["somePublicProperty"]=>
string(11) "some public"
["otherPublicProperty"]=>
string(12) "other public"
["someProtectedProperty":protected]=>
string(14) "some protected"
["otherProtectedProperty":protected]=>
string(15) "other protected"
["somePrivateProperty":"SomeClass":private]=>
string(12) "some private"
["otherPrivateProperty":"SomeClass":private]=>
string(13) "other private"
}
O:9:"SomeClass":6:{s:18:"somePublicProperty";s:11:"some public";s:19:"otherPublicProperty";s:12:"other public";s:24:"*someProtectedProperty";s:14:"some protected";s:25:"*otherProtectedProperty";s:15:"other protected";s:30:"SomeClasssomePrivateProperty";s:12:"some private";s:31:"SomeClassotherPrivateProperty";s:13:"other private";}
Magic method __unserialize
Data:
array(6) {
["somePublicProperty"]=>
string(11) "some public"
["otherPublicProperty"]=>
string(12) "other public"
["*someProtectedProperty"]=>
string(14) "some protected"
["*otherProtectedProperty"]=>
string(15) "other protected"
["SomeClasssomePrivateProperty"]=>
string(12) "some private"
["SomeClassotherPrivateProperty"]=>
string(13) "other private"
}
object(SomeClass)#2 (6) {
["somePublicProperty"]=>
string(11) "some public"
["otherPublicProperty"]=>
string(12) "other public"
["someProtectedProperty":protected]=>
string(29) "hidden during unserialisation"
["otherProtectedProperty":protected]=>
string(29) "hidden during unserialisation"
["somePrivateProperty":"SomeClass":private]=>
string(29) "hidden during unserialisation"
["otherPrivateProperty":"SomeClass":private]=>
string(29) "hidden during unserialisation"
}
Source code: Example
__set_state and __debugInfo__set_statestatic __set_state(array $properties): object
This static method is called for classes exported by var_export().
The only parameter of this method is an array containing exported properties in the form ['property' => value, ...].
Example: Using __set_state()
<?php
class A
{
public $var1;
public $var2;
public static function __set_state($an_array)
{
$obj = new A;
$obj->var1 = $an_array['var1'];
$obj->var2 = $an_array['var2'];
return $obj;
}
}
$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';
$b = var_export($a, true);
var_dump($b);
eval('$c = ' . $b . ';');
var_dump($c);
?>
The above example will output:
string(60) "A::__set_state(array(
'var1' => 5,
'var2' => 'foo',
))"
object(A)#2 (2) {
["var1"]=>
int(5)
["var2"]=>
string(3) "foo"
}
Note: When exporting an object, var_export() does not check whether __set_state() is implemented by the object’s class, so re-importing objects will result in an Error exception, 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().
Example: __set_state magic method
<?php
class SomeClass
{
public const string SOME_CONSTANT = 'SOME LABEL';
private const string HIDDEN_FIELD_MESSAGE = 'hidden';
public string $somePublicProperty = 'some public';
public string $otherPublicProperty = 'other public';
protected string $someProtectedProperty = 'some protected';
public static function __set_state(array $properties): object
{
print(
"Magic method __set_state\n\n"
. "Properties:\n"
);
var_dump($properties);
print(PHP_EOL);
return (object) [
'SOME_CONSTANT' => static::SOME_CONSTANT,
'somePublicProperty' => $properties['somePublicProperty'],
'otherPublicProperty' => static::HIDDEN_FIELD_MESSAGE,
'someProtectedProperty' => static::HIDDEN_FIELD_MESSAGE,
];
}
}
$someObject = new SomeClass();
$result = var_export($someObject, true);
print($result . PHP_EOL . PHP_EOL);
eval('$otherObject = ' . $result . ';');
var_dump($otherObject);
print(PHP_EOL);
Result (PHP 8.4):
\SomeClass::__set_state(array(
'somePublicProperty' => 'some public',
'otherPublicProperty' => 'other public',
'someProtectedProperty' => 'some protected',
))
Magic method __set_state
Properties:
array(3) {
["somePublicProperty"]=>
string(11) "some public"
["otherPublicProperty"]=>
string(12) "other public"
["someProtectedProperty"]=>
string(14) "some protected"
}
object(stdClass)#2 (4) {
["SOME_CONSTANT"]=>
string(10) "SOME LABEL"
["somePublicProperty"]=>
string(11) "some public"
["otherPublicProperty"]=>
string(6) "hidden"
["someProtectedProperty"]=>
string(6) "hidden"
}
Source code: Example
__debugInfo__debugInfo(): array
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.
Example: Using __debugInfo()
<?php
class C {
private $prop;
public function __construct($val) {
$this->prop = $val;
}
public function __debugInfo() {
return [
'propSquared' => $this->prop ** 2,
];
}
}
var_dump(new C(42));
?>
The above example will output:
object(C)#1 (1) {
["propSquared"]=>
int(1764)
}
Example: __debugInfo magic method
<?php
class SomeClass
{
public const string SOME_CONSTANT = 'SOME LABEL';
private const string HIDDEN_FIELD_MESSAGE = 'hidden';
public string $somePublicProperty = 'some public';
public string $otherPublicProperty = 'other public';
protected string $someProtectedProperty = 'some protected';
public function __debugInfo(): array
{
print(
"Magic method __debugInfo\n\n"
);
return [
'SOME_CONSTANT' => static::SOME_CONSTANT,
'somePublicProperty' => $this->somePublicProperty,
'otherPublicProperty' => static::HIDDEN_FIELD_MESSAGE,
'someProtectedProperty' => static::HIDDEN_FIELD_MESSAGE,
];
}
}
$someObject = new SomeClass();
var_dump($someObject);
print(PHP_EOL);
Result (PHP 8.4):
Magic method __debugInfo
object(SomeClass)#1 (4) {
["SOME_CONSTANT"]=>
string(10) "SOME LABEL"
["somePublicProperty"]=>
string(11) "some public"
["otherPublicProperty"]=>
string(6) "hidden"
["someProtectedProperty"]=>
string(6) "hidden"
}
Source code: Example
__clone, __construct, __destruct__cloneCreating a copy of an object with fully replicated properties is not always the wanted behavior. A good example of the need for copy constructors, is if you have an object which represents a GTK window and the object holds the resource of this GTK window, when you create a duplicate you might want to create a new window with the same properties and have the new object hold the resource of the new window. Another example is if your object holds a reference to another object which it uses and when you replicate the parent object you want to create a new instance of this other object so that the replica has its own separate copy.
An object copy is created by using the clone keyword (which calls the object’s __clone() method if possible).
$copy_of_object = clone $object;
When an object is cloned, PHP will perform a shallow copy of all of the object’s properties. Any properties that are references to other variables will remain references.
__clone(): void
Once the cloning is complete, if a __clone() method is defined, then the newly created object’s __clone() method will be called, to allow any necessary properties that need to be changed.
Example: Cloning an object
<?php
class SubObject
{
static $instances = 0;
public $instance;
public function __construct() {
$this->instance = ++self::$instances;
}
public function __clone() {
$this->instance = ++self::$instances;
}
}
class MyCloneable
{
public $object1;
public $object2;
function __clone()
{
// Force a copy of this->object, otherwise
// it will point to same object.
$this->object1 = clone $this->object1;
}
}
$obj = new MyCloneable();
$obj->object1 = new SubObject();
$obj->object2 = new SubObject();
$obj2 = clone $obj;
print "Original Object:\n";
print_r($obj);
print "Cloned Object:\n";
print_r($obj2);
?>
The above example will output:
Original Object:
MyCloneable Object
(
[object1] => SubObject Object
(
[instance] => 1
)
[object2] => SubObject Object
(
[instance] => 2
)
)
Cloned Object:
MyCloneable Object
(
[object1] => SubObject Object
(
[instance] => 3
)
[object2] => SubObject Object
(
[instance] => 2
)
)
Example: __clone magic method
<?php
class SomeClass
{
public OtherClass $someInnerObject;
public OtherClass $otherInnerObject;
public function __construct()
{
$this->someInnerObject = new OtherClass();
$this->otherInnerObject = new OtherClass();
}
public function __clone(): void
{
print(
"Magic method __clone\n\n"
);
$this->someInnerObject = new OtherClass();
}
}
class OtherClass
{
public string $someProperty = 'original';
}
$someObject = new SomeClass();
var_dump($someObject);
print(PHP_EOL);
$otherObject = clone $someObject;
var_dump($otherObject);
print(PHP_EOL);
$someObject->someInnerObject->someProperty = 'modified';
$someObject->otherInnerObject->someProperty = 'modified';
var_dump($otherObject);
print(PHP_EOL);
Result (PHP 8.4):
object(SomeClass)#1 (2) {
["someInnerObject"]=>
object(OtherClass)#2 (1) {
["someProperty"]=>
string(8) "original"
}
["otherInnerObject"]=>
object(OtherClass)#3 (1) {
["someProperty"]=>
string(8) "original"
}
}
Magic method __clone
object(SomeClass)#4 (2) {
["someInnerObject"]=>
object(OtherClass)#5 (1) {
["someProperty"]=>
string(8) "original"
}
["otherInnerObject"]=>
object(OtherClass)#3 (1) {
["someProperty"]=>
string(8) "original"
}
}
object(SomeClass)#4 (2) {
["someInnerObject"]=>
object(OtherClass)#5 (1) {
["someProperty"]=>
string(8) "original"
}
["otherInnerObject"]=>
object(OtherClass)#3 (1) {
["someProperty"]=>
string(8) "modified"
}
}
Source code: Example
__construct__construct(mixed ...$values = ""): void
PHP allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.
Example: __construct magic method
<?php
class SomeClass
{
public static $instanceQuantity = 0;
public string $somePublicProperty;
protected string $someProtectedProperty;
private string $somePrivateProperty;
public function __construct(
string $somePublicValue = 'some public',
string $someProtectedValue = 'some protected',
string $somePrivateValue = 'some private'
) {
print(
"Magic method __construct\n\n"
);
self::$instanceQuantity++;
$this->somePublicProperty = $somePublicValue;
$this->someProtectedProperty = $someProtectedValue;
$this->somePrivateProperty = $somePrivateValue;
}
}
print('Instance quantity: ' . SomeClass::$instanceQuantity . PHP_EOL . PHP_EOL);
$someObject = new SomeClass();
print('Instance quantity: ' . SomeClass::$instanceQuantity . PHP_EOL . PHP_EOL);
var_dump($someObject);
print(PHP_EOL);
$otherObject = new SomeClass(
'pear',
'orange',
'banana'
);
print('Instance quantity: ' . SomeClass::$instanceQuantity . PHP_EOL . PHP_EOL);
var_dump($otherObject);
print(PHP_EOL);
Result (PHP 8.4):
Instance quantity: 0
Magic method __construct
Instance quantity: 1
object(SomeClass)#1 (3) {
["somePublicProperty"]=>
string(11) "some public"
["someProtectedProperty":protected]=>
string(14) "some protected"
["somePrivateProperty":"SomeClass":private]=>
string(12) "some private"
}
Magic method __construct
Instance quantity: 2
object(SomeClass)#2 (3) {
["somePublicProperty"]=>
string(4) "pear"
["someProtectedProperty":protected]=>
string(6) "orange"
["somePrivateProperty":"SomeClass":private]=>
string(6) "banana"
}
Source code: Example
__destruct__destruct(): void
PHP possesses a destructor concept similar to that of other object-oriented languages, such as C++. The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence.
Example: __destruct magic method
<?php
class SomeClass
{
public static $instanceQuantity = 0;
public function __destruct()
{
print(
"Magic method __destruct\n\n"
);
self::$instanceQuantity--;
}
}
function someLocalSpace()
{
$someObject = new SomeClass();
SomeClass::$instanceQuantity++;
print('Instance quantity: ' . SomeClass::$instanceQuantity . PHP_EOL . PHP_EOL);
$otherObject = new SomeClass();
SomeClass::$instanceQuantity++;
print('Instance quantity: ' . SomeClass::$instanceQuantity . PHP_EOL . PHP_EOL);
}
someLocalSpace();
print('Instance quantity: ' . SomeClass::$instanceQuantity . PHP_EOL . PHP_EOL);
Result (PHP 8.4):
Instance quantity: 1
Instance quantity: 2
Magic method __destruct
Magic method __destruct
Instance quantity: 0
Source code: Example
▵ Up ⌂ Home ▲ Previous: Classe members ▼ Next: Constructors and destructors