Sobes.tech
Middle

What are the magic methods in PHP and how are they used?

sobes.tech AI

Answer from AI

Magic methods in PHP are special methods that start with a double underscore (e.g., __construct) and are automatically called in certain situations.

Main magic methods and their usage:

  • __construct(): Called when creating an instance of a class. Used for initializing object properties and performing initial actions.

    <?php
    class MyClass {
        public function __construct() {
            echo "Object created!";
        }
    }
    $obj = new MyClass(); // Outputs "Object created!"
    
  • __destruct(): Called when an object is destroyed (e.g., when the script ends or the object is unset). Used for releasing resources (closing files, database connections).

    <?php
    class MyClass {
        public function __destruct() {
            echo "Object destroyed!";
        }
    }
    $obj = new MyClass();
    unset($obj); // Outputs "Object destroyed!"
    
  • __call(string $name, array $arguments): Called when attempting to invoke an inaccessible or non-existent method on an object. $name contains the method name, and $arguments is an array of arguments.

    <?php
    class MyClass {
        public function __call($name, $arguments) {
            echo "Called inaccessible method '{$name}' with arguments: " . implode(', ', $arguments);
        }
    }
    $obj = new MyClass();
    $obj->nonExistentMethod('arg1', 'arg2'); // Outputs "Called inaccessible method 'nonExistentMethod' with arguments: arg1, arg2"
    
  • __callStatic(string $name, array $arguments): Called when attempting to invoke an inaccessible or non-existent static method in a class context. Similar to __call, but for static calls.

    <?php
    class MyClass {
        public static function __callStatic($name, $arguments) {
            echo "Called inaccessible static method '{$name}' with arguments: " . implode(', ', $arguments);
        }
    }
    MyClass::nonExistentStaticMethod('static_arg'); // Outputs "Called inaccessible static method 'nonExistentStaticMethod' with arguments: static_arg"
    
  • __get(string $name): Called when attempting to access an inaccessible or non-existent property. $name contains the property name.

    <?php
    class MyClass {
        private $data = ['key' => 'value'];
        public function __get($name) {
            if (array_key_exists($name, $this->data)) {
                return $this->data[$name];
            }
            return null;
        }
    }
    $obj = new MyClass();
    echo $obj->key; // Outputs "value"
    echo $obj->nonExistentKey; // Outputs an empty string (depending on the return value null)
    
  • __set(string $name, mixed $value): Called when attempting to set a value to an inaccessible or non-existent property. $name contains the property name, and $value is the value to set.

    <?php
    class MyClass {
        private $data = [];
        public function __set($name, $value) {
            $this->data[$name] = $value;
        }
        public function getData() {
            return $this->data;
        }
    }
    $obj = new MyClass();
    $obj->newKey = 'newValue';
    print_r($obj->getData()); // Outputs Array ( [newKey] => newValue )
    
  • __isset(string $name): Called when isset() or empty() is used on an inaccessible or non-existent property. Returns a boolean.

    <?php
    class MyClass {
        private $data = ['present' => 'value'];
        public function __isset($name) {
            return array_key_exists($name, $this->data);
        }
    }
    $obj = new MyClass();
    var_dump(isset($obj->present));     // Outputs bool(true)
    var_dump(isset($obj->absent));      // Outputs bool(false)
    
  • __unset(string $name): Called when unset() is used on an inaccessible or non-existent property.

    <?php
    class MyClass {
        private $data = ['remove_me' => 'value_to_remove'];
        public function __unset($name) {
            if (array_key_exists($name, $this->data)) {
                unset($this->data[$name]);
                echo "Property '{$name}' removed.\n";
            }
        }
        public function getData() {
            return $this->data;
        }
    }
    $obj = new MyClass();
    print_r($obj->getData());
    unset($obj->remove_me); // Outputs "Property 'remove_me' removed." and removes the element from $data
    print_r($obj->getData());
    
  • __sleep(): Called before serializing an object with serialize(). Should return an array of property names to serialize.

    <?php
    class MyClass {
        public $prop1 = 'value1';
        public $prop2 = 'value2';
        public function __sleep() {
            return ['prop1']; // Only serialize prop1
        }
    }
    $obj = new MyClass();
    $serialized = serialize($obj); // Serializes only prop1
    echo $serialized; // Outputs something like O:7:"MyClass":1:{s:5:"prop1";s:6:"value1";}
    
  • __wakeup(): Called after deserializing an object with unserialize(). Used for restoring database connections or other post-deserialization actions.

    <?php
    class MyClass {
        public $prop1;
        public $resource; // Suppose this is a resource connection
        public function __wakeup() {
            // Re-establish resource, e.g., database connection
            $this->resource = fopen('/tmp/my_file.txt', 'w'); // Example
            echo "Object awakened and resource restored!\n";
        }
        public function __sleep() {
            // Do not serialize the resource
            return ['prop1'];
        }
        public function __destruct() {
            if (is_resource($this->resource)) {
                fclose($this->resource);
                echo "Resource closed.\n";
            }
        }
    }
    $obj = new MyClass();
    $obj->prop1 = 'deserialized value';
    $serialized = serialize($obj);
    unset($obj);
    
    $deserialized_obj = unserialize($serialized); // Calls __wakeup()
    var_dump($deserialized_obj->prop1);
    
  • __toString(): Called when the object is used as a string (e.g., with echo or concatenation). Should return a string representation of the object.

    <?php
    class MyClass {
        public $name = "MyObject";
        public function __toString() {
            return "Object of type MyClass with name: " . $this->name;
        }
    }
    $obj = new MyClass();
    echo $obj; // Outputs "Object of type MyClass with name: MyObject"
    
  • __invoke(...): Called when attempting to invoke an object as a function. Can accept any number of arguments.

    <?php
    class MyCallableClass {
        public function __invoke(...$args) {
            echo "Object was invoked as a function with arguments: " . implode(', ', $args);
        }
    }
    $obj = new MyCallableClass();
    $obj('arg1', 123); // Outputs "Object was invoked as a function with arguments: arg1, 123"
    
  • __set_state(array $properties): Called statically for classes exported with var_export(). Receives an array of exported properties. Should create a new class instance and return it.

    <?php
    class MyClass {
        public $prop;
        public static function __set_state(array $properties) {
            $obj = new MyClass();
            $obj->prop = $properties['prop'];
            return $obj;
        }
    }
    $obj = new MyClass();
    $obj->prop = 'exported value';
    $exported = var_export($obj, true); // Exports the object
    // $exported will contain code to recreate the object using __set_state()
    eval('$restored_obj = ' . $exported . ';');
    var_dump($restored_obj); // Outputs the MyClass object with property 'exported value'
    
  • __debugInfo(): Called when functions like var_dump() are used on the object. Should return an array with information about the object's properties to display.

    <?php
    class MyClass {
        public $publicProp = 'public';
        private $privateProp = 'private';
        public function __debugInfo() {
            return ['publicProp' => $this->publicProp, 'private_info' => 'some details about privateProp'];
        }
    }
    $obj = new MyClass();
    var_dump($obj); // Will display the information returned by __debugInfo()
    
  • __clone(): Called after cloning an object. Used for deep copying internal objects or data structures.

    <?php
    class SubObject {
        public $value;
        public function __construct($value) {
            $this->value = $value;
        }
    }
    class MyClass {
        public $object;
        public $anotherProp;
        public function __construct() {
            $this->object = new SubObject('initial');
            $this->anotherProp = 'original';
        }
        public function __clone() {
            // Deep copy the nested object
            $this->object = clone $this->object;
        }
    }
    $obj = new MyClass();
    $cloned_obj = clone $obj;
    
    // Now $obj->object and $cloned_obj->object are different instances of SubObject
    $cloned_obj->object->value = 'modified';
    
    var_dump($obj->object->value);       // Outputs "initial"
    var_dump($cloned_obj->object->value); // Outputs "modified"
    

Summary table:

Method Description Called when...
__construct() Class constructor. Creating a new class instance.
__destruct() Class destructor. Deleting an object or script termination.
__call() Handling calls to inaccessible/non-existent object methods. Attempting to call an inaccessible or non-existent method of an object.
__callStatic() Handling calls to inaccessible/non-existent static methods. Attempting to call an inaccessible or non-existent static method of a class.
__get() Handling getting the value of inaccessible/non-existent properties. Attempting to get the value of an inaccessible or non-existent property of an object.
__set() Handling setting the value of inaccessible/non-existent properties. Attempting to set the value of an inaccessible or non-existent property of an object.
__isset() Handling isset() or empty() for properties. Calling isset() or empty() on an inaccessible or non-existent property of an object.
__unset() Handling unset() for properties. Calling unset() on an inaccessible or non-existent property of an object.
__sleep() Preparing for serialization. Calling serialize() on an object.
__wakeup() Post-processing after deserialization. Calling unserialize() on an object.
__toString() String representation of the object. Using the object in a string context (e.g., echo).
__invoke() Invoking the object as a function. Attempting to call the object as a function.
__set_state() Creating an object after export with var_export(). Evaluating code generated by var_export().
__debugInfo() Information for debugging functions (var_dump()). Calling var_dump() on the object.
__clone() Post-processing after cloning. Calling clone on the object.
What are the magic methods in PHP and how are they… - sobes.tech