Sobes.tech
Junior

Why are magic methods in PHP called magic?

sobes.tech AI

Answer from AI

They are invoked implicitly, in response to certain actions with an object, not through direct call. This allows creating dynamic behavior of objects and intercepting operations, such as access to properties or calling methods that do not exist.

Examples:

  • __construct(): Called when creating an object.
  • __destruct(): Called when deleting an object.
  • __get(): Called when reading an inaccessible property.
  • __set(): Called when writing to an inaccessible property.
  • __call(): Called when calling an inaccessible method of an instance.
  • __callStatic(): Called when calling an inaccessible static method.
  • __toString(): Called when trying to use an object as a string.
  • __invoke(): Called when trying to invoke an object as a function.
<?php

class MagicExample {
    private $data = [];

    public function __set($name, $value) {
        // Access to inaccessible property via $object->name = $value;
        echo "Setting '$name' to '$value'\n";
        $this->data[$name] = $value;
    }

    public function __get($name) {
        // Reading inaccessible property via $object->name;
        echo "Getting '$name'\n";
        return array_key_exists($name, $this->data) ? $this->data[$name] : null;
    }

    public function __call($name, $arguments) {
        // Calling inaccessible method via $object->method($arg1, ...);
        echo "Calling method '$name' with arguments: " . implode(', ', $arguments) . "\n";
        // Logic for handling call
    }

    public static function __callStatic($name, $arguments) {
         // Calling inaccessible static method via ClassName::method($arg1, ...);
         echo "Calling static method '$name' with arguments: " . implode(', ', $arguments) . "\n";
         // Static call handling logic
    }

    public function __toString() {
        // Convert object to string via (string) $object; or echo $object;
        return "This is a MagicExample object";
    }

    public function __invoke(...$args) {
        // Call object as a function via $object($arg1, ...);
        echo "Object invoked as a function with arguments: " . implode(', ', $args) . "\n";
    }
}

$obj = new MagicExample();

$obj->prop1 = "value1"; // Calls __set()
echo $obj->prop1 . "\n"; // Calls __get()

$obj->nonExistentMethod(1, 2); // Calls __call()
MagicExample::staticNonExistentMethod(3, 4); // Calls __callStatic()

echo $obj . "\n"; // Calls __toString()

$obj("arg1", "arg2"); // Calls __invoke()

?>