Magic Methods
Chapter Overview
In this chapter you will learn:
- What magic methods are
- Why magic methods exist
- Object lifecycle
- Dynamic properties
- Serialization
- Method overloading
- Cloning
- Object invocation
- Debugging helpers
- Real-world examples
- Laravel examples
- PocketMine examples
- Enterprise usage
What are Magic Methods?
Magic methods are special methods in PHP that begin with:
__
(two underscores)
Example:
__construct()
They allow PHP to automatically execute code during specific events.
Examples:
Object Creation
Object Destruction
Property Access
Method Calls
Serialization
Cloning
Printing Objects
List of Magic Methods
__construct()
__destruct()
__get()
__set()
__isset()
__unset()
__call()
__callStatic()
__toString()
__invoke()
__clone()
__sleep()
__wakeup()
__serialize()
__unserialize()
__debugInfo()
Object Lifecycle
Create Object
↓
Constructor
↓
Use Object
↓
Destroy Object
Magic methods allow us to control this process.
__construct()
What is Constructor?
Constructor runs automatically when object is created.
Example:
class Player {
public function __construct() {
echo "Player Created";
}
}
Usage:
$player =
new Player();
Output:
Player Created
Constructor with Parameters
class Player {
public function __construct(
private string $name
) {
}
}
Usage:
$player =
new Player(
"Aayan"
);
Why Constructors Exist
To initialize objects.
Examples:
Database Connections
Configurations
Services
Dependency Injection
Real Example
class Database {
public function __construct() {
$this->connect();
}
}
Laravel Example
public function __construct(
UserRepository $users
)
Dependency Injection.
__destruct()
Destructor runs automatically when object is destroyed.
Example:
class Test {
public function __destruct() {
echo "Destroyed";
}
}
Usually runs:
End of Script
or when object has no references.
Real Example
class Database {
public function __destruct() {
$this->connection
->close();
}
}
Use Cases
Closing Files
Closing Database Connections
Logging
Cleanup
__toString()
Called when object is treated as a string.
Example:
class User {
public function __toString()
: string {
return "Aayan";
}
}
Usage:
$user =
new User();
echo $user;
Output:
Aayan
Without __toString():
Fatal Error
Object cannot be converted to string
Real Example
class Position {
public function __toString()
: string {
return
$this->x .
"," .
$this->y .
"," .
$this->z;
}
}
Output:
100,64,200
__get()
Called when accessing inaccessible properties.
Example:
class User {
private array $data = [];
public function __get(
string $name
) {
return
$this->data[$name]
?? null;
}
}
Usage:
echo $user->name;
Even if property doesn't exist.
Real Example
Laravel uses this heavily.
Example:
$user->posts
Internally:
__get()
loads relation.
__set()
Called when assigning inaccessible properties.
Example:
class User {
private array $data = [];
public function __set(
string $name,
mixed $value
) {
$this->data[$name]
= $value;
}
}
Usage:
$user->name =
"Aayan";
__isset()
Called by:
isset()
Example:
public function __isset(
string $name
)
{
return isset(
$this->data[$name]
);
}
Usage:
isset(
$user->name
);
__unset()
Called when:
unset()
is used.
Example:
public function __unset(
string $name
)
{
unset(
$this->data[$name]
);
}
Dynamic Property System
Visualization:
$user->name
↓
__set()
↓
internal array
Laravel models work similarly.
__call()
Called when calling inaccessible methods.
Example:
class User {
public function __call(
string $method,
array $arguments
) {
echo
"Method:
$method";
}
}
Usage:
$user->hello();
Output:
Method: hello
Why Useful?
Create dynamic APIs.
Laravel Example
User::whereName(
"Aayan"
);
Internally uses:
__call()
__callStatic()
Same as __call()
But for:
Static Methods
Example:
class User {
public static function __callStatic(
string $method,
array $arguments
) {
}
}
Usage:
User::findByName();
__invoke()
Makes object callable like a function.
Example:
class Hello {
public function __invoke() {
echo "Hello";
}
}
Usage:
$hello =
new Hello();
$hello();
Output:
Hello
Real Example
Middleware systems often use:
$middleware(
$request
);
__clone()
Called when object is cloned.
Example:
class User {
public function __clone() {
echo "Cloned";
}
}
Usage:
$user2 =
clone $user1;
Why?
Objects are copied.
Sometimes IDs should reset.
Example:
public function __clone() {
$this->id = null;
}
__sleep()
Older serialization method.
Called before:
serialize()
Example:
public function __sleep()
{
return ["name"];
}
__wakeup()
Called after:
unserialize()
Example:
public function __wakeup() {
$this->connect();
}
__serialize()
PHP 7.4+
Modern serialization method.
Example:
public function __serialize()
: array {
return [
"name" =>
$this->name
];
}
__unserialize()
Example:
public function __unserialize(
array $data
)
{
$this->name =
$data["name"];
}
Why Serialization Exists
Examples:
Caching
Sessions
Saving Objects
Queue Systems
__debugInfo()
Called when:
var_dump()
is executed.
Example:
public function __debugInfo()
{
return [
"name" => "Aayan"
];
}
Usage:
var_dump(
$user
);
Real World Example
ORM Models
Laravel models heavily use:
__get()
__set()
__call()
Dependency Containers
Often use:
__invoke()
Service Providers
Use:
__callStatic()
PocketMine Examples
Position Objects
Could implement:
__toString()
Config Wrappers
Can use:
__get()
__set()
Event Dispatchers
Can use:
__invoke()
Visualization
Object
│
├── __construct()
├── __get()
├── __set()
├── __call()
├── __invoke()
├── __clone()
└── __destruct()
Common Beginner Mistakes
Abusing __get()
Makes debugging difficult.
Creating Everything Dynamically
Static code is easier to understand.
Overusing Magic Methods
Too much magic:
Creates confusing code.
Good Usage
✅ ORMs
✅ Dynamic APIs
✅ Caching
✅ Service Containers
Bad Usage
❌ Everything hidden.
❌ Replacing normal methods.
❌ Making code impossible to understand.
Exercises
Exercise 1
Create:
User
using:
__get()
__set()
Exercise 2
Create:
Position
with:
__toString()
Exercise 3
Create:
Logger
using:
__invoke()
Mini Project
Create:
Zyro User Model
Features:
Dynamic Attributes
Serialization
String Conversion
Method Overloading
Implement:
__get()
__set()
__serialize()
__toString()
Interview Questions
What are magic methods?
Special methods automatically called by PHP.
Which magic method runs when object is created?
__construct()
Which magic method runs when object becomes string?
__toString()
Which method handles unknown properties?
__get()
__set()
Which method makes objects callable?
__invoke()
Which method handles cloning?
__clone()
Summary
Magic Methods allow:
✅ Dynamic APIs
✅ Object Lifecycle Control
✅ Serialization
✅ Method Overloading
✅ Framework Features
✅ ORMs and Containers
They are extremely powerful but should be used carefully.
References
https://www.php.net/manual/en/language.oop5.magic.php
Next Chapter
➡ Enums
➡ Namespaces
➡ Autoloading
➡ Dependency Injection