100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
PHP

Magic Methods

Magic methods are special, double-underscore-prefixed hooks PHP invokes automatically for events like object construction, property access, and string conversion.

Object-Oriented PHPIntermediate10 min readJul 9, 2026
Analogies

Magic Methods

PHP reserves method names beginning with two underscores as 'magic methods' — hooks the engine calls automatically in response to specific events on an object, rather than being called explicitly by name. __construct() and __destruct() are the most familiar examples, firing on object creation and garbage collection. Beyond those, PHP defines magic methods for intercepting property access on undefined or inaccessible properties (__get, __set, __isset, __unset), calling undefined or inaccessible methods (__call, __callStatic), converting an object to a string (__toString), controlling serialization (__sleep, __wakeup, __serialize, __unserialize), cloning (__clone), and invoking an object as if it were a function (__invoke). Used well, magic methods enable elegant APIs like fluent builders and transparent proxies; used carelessly, they make code behave unpredictably and are notoriously hard to debug.

🏏

Cricket analogy: A stadium's automatic floodlight system triggers itself the instant the umpire signals bad light, without anyone flipping a switch by name — just as PHP's magic methods fire automatically on events like object creation, not by explicit call.

Property interception: __get, __set, __isset, __unset

__get(string $name) and __set(string $name, $value) fire only when code accesses a property that is either undeclared or declared private/protected from outside the class's visibility scope — they never intercept normal access to a public, declared property. __isset($name) backs isset()/empty() checks on those same inaccessible properties, and __unset($name) backs unset(). This quartet is commonly used to implement virtual properties, lazy-loaded attributes, or to log/validate access to a data structure.

🏏

Cricket analogy: A player's private training diary is off-limits to teammates by default, but a team manager checking in via an authorized liaison (like __get) can request a peek without directly opening the diary themselves, since direct access to a protected page is denied.

php
<?php
declare(strict_types=1);

final class Config
{
    private array $data = [];

    public function __get(string $name): mixed
    {
        return $this->data[$name] ?? throw new \OutOfBoundsException("Unknown config key: $name");
    }

    public function __set(string $name, mixed $value): void
    {
        $this->data[$name] = $value;
    }

    public function __isset(string $name): bool
    {
        return isset($this->data[$name]);
    }
}

$config = new Config();
$config->timeout = 30;         // triggers __set
echo $config->timeout;          // triggers __get -> 30
var_dump(isset($config->retries)); // triggers __isset -> false

__call, __toString, and __invoke

__call(string $name, array $arguments) intercepts calls to inaccessible or non-existent instance methods, and its static twin __callStatic does the same for static calls — both are the backbone of fluent query builders and mock objects that need to respond to arbitrary method names. __toString() lets an object be used anywhere a string is expected, such as string interpolation or echo, and must return a string. __invoke(...$args) lets an object be called directly like $obj(...), which is useful for building single-purpose callable objects that carry configuration as instance state.

🏏

Cricket analogy: A commentary team's flexible 'ask the analyst anything' segment intercepts any question thrown at it and generates a relevant answer on the fly, much like __call intercepting arbitrary method names to build a fluent response, rather than having a fixed script for every possible question.

php
<?php
declare(strict_types=1);

final class Money
{
    public function __construct(private readonly int $cents, private readonly string $currency = 'USD') {}

    public function __toString(): string
    {
        return sprintf('%.2f %s', $this->cents / 100, $this->currency);
    }
}

final class Multiplier
{
    public function __construct(private readonly int $factor) {}

    public function __invoke(int $value): int
    {
        return $value * $this->factor;
    }
}

echo "Total: " . new Money(4599);   // Total: 45.99 USD (via __toString)

$double = new Multiplier(2);
echo $double(21);                    // 42 (via __invoke)

__toString() is what allows an exception object to be printed directly, and it's why PHP lets you do echo $someObject; for value objects like Money or DateTime-like wrappers without calling an explicit ->format() or ->toString() method every time.

__get/__set and __call are easy to overuse. Because they intercept *any* undefined property or method name, typos silently succeed instead of triggering a clear 'undefined property' error — a call to $config->timout (misspelled) may quietly return null or throw a vague exception deep inside __get rather than an immediate, obvious PHP error. Prefer explicit, declared, typed properties and methods whenever the full set of names is known ahead of time.

  • Magic methods are invoked automatically by PHP in response to object lifecycle or access events, not called directly by name.
  • __get/__set/__isset/__unset only fire for undefined or inaccessible properties, never for normal public property access.
  • __call/__callStatic intercept calls to undefined or inaccessible methods and are the basis of fluent builders and proxies.
  • __toString() must return a string and allows objects to be used in string contexts like echo and interpolation.
  • __invoke() lets an object be called as a function, useful for encapsulating configured, reusable callables.
  • Overusing magic methods trades explicitness for flexibility and can mask typos and bugs — use them deliberately, not by default.

Practice what you learned

Was this page helpful?

Topics covered

#PHP#PHPProgrammingStudyNotes#Programming#MagicMethods#Magic#Methods#Property#Interception#Functions#StudyNotes#SkillVeris