Magic Methods

Back

Loading concept...

🪄 PHP Magic Methods: Your Object’s Secret Superpowers

Imagine your PHP object is a smart robot helper. Magic methods are like special buttons hidden inside that robot. When someone tries to do something specific—like read a secret note or turn the robot into a string—the magic button automatically activates!


🎯 What Are Magic Methods?

Magic methods are special functions in PHP that start with two underscores (__). They automatically run when certain things happen to your object.

Think of it like this:

  • You have a toy box (your object)
  • When someone opens it → a music plays automatically
  • When someone closes it → lights turn off automatically
  • These automatic actions = Magic Methods!

📦 Property Overloading: The Invisible Storage Room

What Is It?

Property overloading lets your object pretend it has properties that don’t actually exist in code.

Analogy: Imagine a magic backpack. You can put anything in it and take anything out—even things you never packed! The backpack just creates them for you.

The Magic Methods

class MagicBackpack {
    private $items = [];

    // Called when READING a missing property
    public function __get($name) {
        return $this->items[$name] ?? "Not found!";
    }

    // Called when WRITING to a missing property
    public function __set($name, $value) {
        $this->items[$name] = $value;
    }

    // Called when checking if property EXISTS
    public function __isset($name) {
        return isset($this->items[$name]);
    }

    // Called when DELETING a property
    public function __unset($name) {
        unset($this->items[$name]);
    }
}

Using The Magic Backpack

$bag = new MagicBackpack();

// __set is called (sandwich doesn't exist!)
$bag->sandwich = "Turkey";

// __get is called
echo $bag->sandwich; // "Turkey"

// __isset is called
if (isset($bag->sandwich)) {
    echo "Lunch is packed!";
}

// __unset is called
unset($bag->sandwich);

🧠 When Does Each Magic Trigger?

Action Magic Method Example
Read unknown property __get $bag->apple
Write unknown property __set $bag->apple = 5
Check with isset() __isset isset($bag->apple)
Delete with unset() __unset unset($bag->apple)

📞 Method Overloading: The Universal Phone Line

What Is It?

Method overloading lets your object respond to method calls that don’t exist!

Analogy: Imagine calling a restaurant and asking for “pizza with extra sparkles.” The restaurant doesn’t have that on the menu, but instead of hanging up, they figure out what you want and make it happen!

The Magic Methods

class SmartAssistant {
    // Called for non-existent regular methods
    public function __call($name, $arguments) {
        echo "You called: $name\n";
        echo "With: " . implode(', ', $arguments);
        return "Done!";
    }

    // Called for non-existent STATIC methods
    public static function __callStatic($name, $args) {
        echo "Static call to: $name";
        return "Static Done!";
    }
}

Using The Smart Assistant

$assistant = new SmartAssistant();

// These methods DON'T exist, but work anyway!
$assistant->orderPizza("large", "pepperoni");
// Output: You called: orderPizza
//         With: large, pepperoni

$assistant->singHappyBirthday("Mom");
// Output: You called: singHappyBirthday
//         With: Mom

// Static call to non-existent method
SmartAssistant::doMagicTrick();
// Output: Static call to: doMagicTrick

🎯 Real-World Use Case

class DatabaseQuery {
    public function __call($name, $args) {
        // findByName, findByEmail, findByAge all work!
        if (strpos($name, 'findBy') === 0) {
            $column = strtolower(substr($name, 6));
            return "SELECT * FROM users
                    WHERE $column = '{$args[0]}'";
        }
    }
}

$db = new DatabaseQuery();
echo $db->findByEmail("test@mail.com");
// SELECT * FROM users WHERE email = 'test@mail.com'

🎭 __toString: Your Object’s Self-Introduction

What Is It?

The __toString method tells PHP how to convert your object into text.

Analogy: When someone asks “Who are you?”, instead of showing your internal organs (yuck!), you say your name nicely. __toString is your object saying “Hi, I’m…”

The Magic Method

class Pet {
    public $name;
    public $type;
    public $age;

    public function __construct($name, $type, $age) {
        $this->name = $name;
        $this->type = $type;
        $this->age = $age;
    }

    public function __toString() {
        return "🐾 {$this->name} the {$this->type},
                {$this->age} years old";
    }
}

Using __toString

$pet = new Pet("Whiskers", "Cat", 3);

// Without __toString: Error!
// With __toString: Magic!
echo $pet;
// Output: 🐾 Whiskers the Cat, 3 years old

// Works in string contexts too
$message = "My pet is: " . $pet;
echo $message;
// My pet is: 🐾 Whiskers the Cat, 3 years old

⚠️ Important Rule

// __toString MUST return a STRING
// This would cause an error:
public function __toString() {
    return 42; // ❌ Error! Not a string!
}

// This is correct:
public function __toString() {
    return "42"; // ✅ String is fine!
}

🎪 __invoke: Your Object Becomes Callable!

What Is It?

The __invoke method lets you use your object like a function!

Analogy: Imagine a robot that you can just tap to make it work. No buttons, no switches—just tap and it does its thing! __invoke makes your object “tappable.”

The Magic Method

class Calculator {
    private $multiplier;

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

    public function __invoke($number) {
        return $number * $this->multiplier;
    }
}

Using __invoke

$double = new Calculator(2);
$triple = new Calculator(3);

// Using objects like functions!
echo $double(5);  // 10 (5 × 2)
echo $triple(5);  // 15 (5 × 3)

// Check if callable
var_dump(is_callable($double)); // true

🎯 Practical Example: Validator

class AgeValidator {
    private $minAge;
    private $maxAge;

    public function __construct($min, $max) {
        $this->minAge = $min;
        $this->maxAge = $max;
    }

    public function __invoke($age) {
        return $age >= $this->minAge
            && $age <= $this->maxAge;
    }
}

$teenCheck = new AgeValidator(13, 19);

echo $teenCheck(15) ? "Teen!" : "Not teen"; // Teen!
echo $teenCheck(25) ? "Teen!" : "Not teen"; // Not teen

📦 Serialization Methods: Freeze & Unfreeze Your Object

What Is Serialization?

Serialization is turning your object into a string so you can save it or send it somewhere. Unserialization is turning that string back into an object.

Analogy: Imagine freeze-drying a strawberry. You can store it forever, then add water to bring it back to life! Serialization = freeze-dry, Unserialization = add water.

The Magic Methods

class GameSave {
    public $playerName;
    public $level;
    public $score;
    private $password; // Secret!

    // What to save when serializing
    public function __sleep() {
        echo "Saving game...\n";
        // Return property names to save
        return ['playerName', 'level', 'score'];
        // Notice: password NOT included!
    }

    // What to do when unserializing
    public function __wakeup() {
        echo "Loading game...\n";
        // Reconnect to database, set defaults, etc.
        $this->password = null;
    }
}

Using Serialization

$game = new GameSave();
$game->playerName = "Hero123";
$game->level = 5;
$game->score = 1000;

// Serialize (freeze the object)
$savedGame = serialize($game);
// Output: Saving game...
// $savedGame is now a long string

echo $savedGame;
// O:8:"GameSave":3:{s:10:"playerName"...

// Unserialize (bring it back!)
$loadedGame = unserialize($savedGame);
// Output: Loading game...

echo $loadedGame->playerName; // Hero123
echo $loadedGame->level;      // 5

🆕 Modern Alternative: __serialize & __unserialize

PHP 7.4+ introduced cleaner methods:

class ModernGameSave {
    public $player;
    public $level;
    private $secret;

    // Control what gets serialized
    public function __serialize(): array {
        return [
            'player' => $this->player,
            'level' => $this->level
            // secret is excluded
        ];
    }

    // Control how to restore
    public function __unserialize(array $data): void {
        $this->player = $data['player'];
        $this->level = $data['level'];
        $this->secret = "reset"; // Default value
    }
}

🎯 Comparison Table

Old Way New Way Purpose
__sleep() __serialize() Before saving
__wakeup() __unserialize() After loading

🗺️ Visual Overview

graph LR A["Magic Methods"] --> B["Property Overloading"] A --> C["Method Overloading"] A --> D["__toString"] A --> E["__invoke"] A --> F["Serialization"] B --> B1["__get - read"] B --> B2["__set - write"] B --> B3["__isset - check"] B --> B4["__unset - delete"] C --> C1["__call - instance"] C --> C2["__callStatic - static"] F --> F1["__sleep / __serialize"] F --> F2["__wakeup / __unserialize"]

🎓 Quick Reference Card

Magic Method When It Fires Returns
__get($name) Read unknown property The value
__set($name, $value) Write unknown property void
__isset($name) isset() on unknown bool
__unset($name) unset() on unknown void
__call($name, $args) Call unknown method anything
__callStatic($name, $args) Static unknown method anything
__toString() Object used as string string
__invoke(...$args) Object used as function anything
__sleep() Before serialize() array
__wakeup() After unserialize() void

🎉 You Did It!

You now understand PHP’s magic methods! Remember:

  1. Property Overloading = Catch missing property access
  2. Method Overloading = Catch missing method calls
  3. __toString = Object introduces itself as text
  4. __invoke = Object becomes a function
  5. Serialization = Freeze and unfreeze objects

These are your object’s superpowers. Use them wisely! 🦸‍♂️

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.