Logo
Code Ranks ×

20 Magic Methods in PHP | Coderanks

08/04/2019  .   15 minutes, 47 seconds to read  .   Posted by Admin
#codeigniteremail #XMLHandling #mysql #ViewsinCodeigniter #phpmyadmin #best-practices #Laravel #WEBAPI #Jquery #admin #Javascript #json

In object-oriented programming, PHP provides 'magic' methods that allow you to do work efficiently, neatly and tricky. These are identified by (__) a two underscore prefix, all of them declared as public methods or functions.

These methods are:

Method Description
__construct() It is the constructor of a class and called when an object of the class created.
__destruct() It is the destructor of a class and called when an object of the class destroyed.
__get($functionName, $functionarguments) It is called when trying to access private property or a member variable of a class.
__set($functionName, $functionarguments) It is called when trying to set a private property or a member variable of a class.
__call($propertyName) It is called when an undefined or inaccessible method or function is set.
__callStatic($propertyName, $propertyvalue) It is called when an undefined or inaccessible static method or function is set.
__isset($content) it is called when the isset()  or empty() is called on undefined or inaccessible variable or property, this method is set.
__unset($content) It is called when the unset()  or empty() is called on undefined or inaccessible variable or property.
__sleep()  It will be called first when executing serialize() due to its priority order.
__wakeup() It will be called first when deserialization() is executed to reset the serialize().
__toString() It is called when using echo method to print out an object of the class directly.
__invoke() It is called When an object of the class treated as a function.
__set_state($array) It is called When var_export() is set to export the class code to set a specific state for the property of the class.
__clone() It is called to clone or copy an object of a class.
__autoload($className) It is called when tried to autoload the object of the classes or try to load an undefined class.
__debugInfo() It is called to print debug information of the object of a class.

Is it possible that you could define some scenarios, methods or events may cause an error in the future and when it happened, your code would automatically call or triggered some relevant piece of code to avoid or do an action what you want it to do?

1.__construct()

This magic function is probably the most used function in OOP PHP. The basic purpose for it to initialize itself when the class object is created. For example, if you want to check the date when your code is in a ready state or Object created, just do the following at the top of the code.

It is also important to remember that the constructor changes its behaviour towards the nature of class whether the class is a parent or a child and the child class has a parent constructor inside the __construct() method.

<?php
class Teacher
{
    function __construct()
    {
        echo "Hello Teacher in Parent Constructor.<br>";
    }
}
 
class Student extends Teacher
{
 
    function __construct()
    {
        parent::__construct();
        echo "Hello Student in Child Constructor.<br>";
    }
}

$greetingTeacher = new Teacher();
// the code will output:
// Hello Teacher in Parent Constructor

$greetingStudent = new Student();

// the code will output:
// Hello Teacher in Parent Constructor
// Hello Student in Child Constructor
?>

2.__destruct()

This magic function is opposite to the construct function in OOP PHP. The basic purpose for it to destroy itself when the class object is destroyed. For example, if you want to unset variables or a piece of instructions which were set into the constructor method when your Object is destroyed, just call the destruct function/method anywhere after construct function in the class.

It is also important to remember that the destructor changes its behaviour towards the nature of class whether the class is a parent or a child and the child class has a parent destructor inside the __destruct() method.

<?php
class Teacher{     

    public $name;      

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

    public function say()
    {
        echo "Name?".$this->name;
    }   

    public function __destruct()
    {
            echo "Well, Teacher Name is ".$this->name;
    }
}

$Teacher = new Teacher("John");
unset($Person);

//destroy the object of $Person created above
// output
// Well, Teacher Name is John
?>

3.__get()

In this magic function, there is a little, neat and tricky approach to use. When someone tried to access the private property of a class from an external object in a program, the program should send an exception and terminate the execution of the program. The get method with its magical property to solve these kinds of problems be used. It has the ability to get values of the private property through the object beyond the scope of the object.

<?php
class Teacher
{
    private $teacherName;
    private $teacherAge;

    function __construct($teacherName="", $teacherAge=10)
    {
        $this->teacherName = $teacherName;
        $this->teacherAge = $teacherAge;
    }

    public function __get($propertyteacherName)
    {   
        if ($propertyteacherName == "teacherAge") {
            if ($this->teacherAge > 30) {
                return $this->teacherAge - 10;
            } else {
                return $this->$propertyteacherName;
            }
        } else {
            return $this->$propertyteacherName;
        }
    }
}
$Teacher1 = new Teacher("John", 60); //Intialize object with arguments
$Teacher2 = new Teacher("John", 20); //Intialize object with arguments
echo "Teacher Name: " . $Teacher1->teacherName . "<br>";   
echo "Teacher Age: " . $Teacher1->teacherAge . "<br>";    
echo "Teacher Name: " . $Teacher2->teacherName . "<br>";  
echo "Teacher Age: " . $Teacher2->teacherAge . "<br>"; 


// output is

// Teacher Name: John
// Teacher Age: 50
// Teacher Name: John
// Teacher Age: 20
?>

4.__set()

In this magic function, there is an awful approach to use. When someone tried to access the private property of a class from an external object in a program, the program should send an exception and terminate the execution of the program. The set method with its magical property to solve these kinds of problems be used. It has the ability to set values of the private property through the object beyond the scope of the object.

It has two parameters to set named as property and value. The syntax should look like __set($propertyName, propertyValue).

<?php
class Teacher
{
    private $teacherName;
    private $teacherAge;

    public function __construct($teacherName="",  $teacherAge=25)
    {
        $this->teacherName = $teacherName;
        $this->teacherAge  = $teacherAge;
    }

    public function __set($property, $value) {
        if ($property=="age")
        {
            if ($value < 25 || $value > 0) {
                return;
            }
        }
        $this->$property = $value;
    }

    public function introduction(){
        echo "My Name is ".$this->teacherName." and I'm ".$this->teacherAge." Years Old";
    }
}

$Teacher=new Teacher("John", 25);// initialize the Object
$Teacher->teacherName = "Doe"; //exception function
$Teacher->teacherAge = 16; //The "age" is relevant and will be set successfully.
$Teacher->introduction();

// output is

// My Name is Doe and I'm 16 Years Old
?>

 5.__call()

In this magic function, there are two parameters to use, the first one is the name of the method as $method_name and on the second multiple arguments of the function or method given as an array.

When an undefined method or function is called with the object of a class, the __call() method will be replaced or called automatically.

<?php
class Teacher
{                             
    function name()
    {
           echo "John Doe";
    }     

    function __call($functionName, $functionArguments)
    {
          echo "The Function Name: " . $functionName . "(Function Arguments?" ; Not existed Function name output.
          echo '<pre>',print_r($functionArguments); Not existed functionArguments output.
          echo ")Does't Exist!?<br><br>";                   
    }                                         
}
$Teacher = new Teacher();           
$Teacher->school("CodeRanks");
$Teacher->Subject("PHP", "Web Development");             
$Teacher->name();

// output for this
//  The Function Name: school(Function Arguments?
// Array
// (
//    [0] => CodeRanks
// )
// 1)Does't Exist!?

// The Function Name: Subject(Function Arguments?
// Array
// (
//    [0] => PHP
//    [1] => Web Development
// )
// 1)Does't Exist!?

// John Doe
?>

6.__callStatic()

In this magic function, there are two parameters to use, the first one is the name of the method as $method_name and on the second multiple arguments of the function or method given as an array.

When an undefined static method or function is called with the object of a class, the __callStatic() method will be replaced or called automatically.

The callStatic method should be Public and Static in behaviour like public static function functionName($functionName, $functionArguments).

<?php
class Teacher
{                             
    function name()
    {
           echo "John Doe";
    }     

    public static function __callStatic($functionName, $functionArguments)
    {
          echo "The Static Function Name: " . $functionName . "(With Function Arguments?" ; // functionName output
          echo '<pre>',print_r($functionArguments); // functionArguments output in array
          echo ")Does't Exist!?<br><br>";                   
    }                                         
}
$Teacher = new Teacher();           
$Teacher::school("CodeRanks"); 
$Teacher::Subject("PHP", "Web Development");             
$Teacher->name();

// output for this
//  The Static Function Name: school(With Function Arguments?
// Array
// (
//    [0] => CodeRanks
// )
// 1)Does't Exist!?

// The Static Function Name: Subject(With Function Arguments?
// Array
// (
//    [0] => PHP
//    [1] => Web Development
// )
// 1)Does't Exist!?

// John Doe

7.__isset()

This magic method is widely used to avoid variable errors. In most cases, we're facing the error that Undefined variable is used, to avoid this, we're using the variable with the isset method which determined either the variable is set or not. Note that if the Method called from outside of the object for private property, the isset method doesn't work.

So, when the isset()  or empty() is called on undefined or inaccessible variable or property, the __isset() function or method is set.

<?php
class Teacher
{
    private $teacherName;
    private $teacherAge;

    public function __construct($teacherName="",  $teacherAge=25)
    {
        $this->name = $teacherName;
        $this->age  = $teacherAge;
    }

    public function __isset($property) {
        echo "The {$property} variable or method is a private property?So the __isset() function is called automatically.<br>";
   }
}

$Teacher = new Teacher("John", 25); // Initially assigned.
echo isset($Teacher->teacherName),"<br>";
echo isset($Teacher->teacherAge),"<br>";

// output is

// The teacherName variable or method is a private property?So the __isset() function is called automatically.

// The teacherAge variable or method is a private property?So the __isset() function is called automatically.
?>

8.__unset()

This magic method is very similar to the isset() method. So, when the unset()  or empty() is called on undefined or inaccessible variable or property, the __unset() function or method is called or set automatically.

<?php
class Teacher
{
    private $teacherName;
    private $teacherAge;

    public function __construct($teacherName="",  $teacherAge=25)
    {
        $this->name = $teacherName;
        $this->age  = $teacherAge;
    }
    public function __unset($property) {
        echo "the __unset() function or method is called or set automatically for ".$property." private property.<br>";
    }
}

$Teacher = new Teacher("John", 25); // Initially assign values for object.
unset($Teacher->teacherName);"<br>";
unset($Teacher->teacherAge);"<br>";

// output is

// the __unset() function or method is called or set automatically for teacherName property.
// the __unset() function or method is called or set automatically for teacherAge property.
?>

9.__sleep()

The built-in method serialize() returns a byte-stream string which represents any value that can be stored or contained in PHP.

To understand the magic method sleep we've to use the serialize() method for its flow and unique property. The serialize() method firstly checked that is there is a __sleep() method in this class. If it is set, the serialize() method sets it to first and then the rest of the functionality performed due to its priority order.

The __sleep() method is often used to avoid unnecessary data before saving it. We'd use the serialize() method before saving data and set some objects in __sleep() method which was very large and doesn't have any need to store. This method is very very useful for these kinds of situations.

<?php
class Teacher
{
    public $teacherName;
    public $teacherAge;

    public function __construct($teacherName="",  $teacherAge=25)
    {
        $this->name = $teacherName;
        $this->age  = $teacherAge;
    }
 
    public function __sleep() {
        echo "When the serialize() method is set from outside the class.<br>";
        $this->teacherName = base64_encode($this->teacherName);
        return array('name', 'age'); // It must return a value of which the elements are the name of the properties returned.
    }
}

$Teacher = new Teacher('John'); // Initially assigned.
echo serialize($Teacher);
echo '<br/>';

// output is 

// When the serialize() method is set from outside the class.
// O:7:"Teacher":2:{s:4:"name";s:4:"John";s:3:"age";i:25;}

?>

10.__wakeup()

This magic method is totally opposite to the magic method __sleep(). It is often used to deserialized the variable or objects which were in a ready state to use again, such as re-connect to the database etc.

<?php
class Teacher
{
    public $teacherName;
    public $teacherAge;

    public function __construct($teacherName="",  $teacherAge=25)
    {
        $this->name = $teacherName;
        $this->age  = $teacherAge;
    }

    public function __sleep() {
        echo "When the serialize() method is called from outside the class.<br>";
        $this->teacherName = base64_encode($this->teacherName);
        return array('name', 'age'); // return array values
    }

    public function __wakeup() {
        echo "When the unserialize() method is called from outside the class.<br>";
        $this->teacherName = 'Doe';
        $this->teacherAge = 25; // No return needed
    }
}

$Teacher = new Teacher('John'); // Initially assign values to object.
var_dump(serialize($Teacher));
var_dump(unserialize(serialize($Teacher)));

// output is

// When the serialize() method is called from outside the class.
// C:\wamp64\www\registration-magic\magic.php:31:string 'O:7:"Teacher":2:{s:4:"name";s:4:"John";s:3:"age";i:25;}' (length=55)
// When the serialize() method is called from outside the class.
// When the unserialize() method is called from outside the class.
// C:\wamp64\www\registration-magic\magic.php:32:
// object(Teacher)[2]
//  public 'teacherName' => string 'Doe' (length=3)
//  public 'teacherAge' => int 25
//  public 'name' => string 'John' (length=4)
//  public 'age' => int 25
?>

11. __toString()

The next magic method is used to directly called the echo method to print out the object of a class. Note that just as its name, the function just returns a string otherwise there will be strong chances to throw an error or fatal error in worst situations. On the other hand, you cannot use it to throw the exceptions.

<?php
class Teacher
{
    public $teacherName;

    public function __construct($teacherName="")
    {
        $this->name = $teacherName;
    }

    public function __toString()
    {
        return  'You Called the Object of the Class Directly';
    }
}

$Teacher = new Teacher('John'); // Initially assign values to object of class.
echo $Teacher;

// output is

// You Called the Object of the Class Directly

?>

What if the __toString() method don't define in the Class. Let's have a look.

<?php
class Teacher
{
    public $teacherName;

    public function __construct($teacherName="")
    {
        $this->name = $teacherName;
    }
}

$Teacher = new Teacher('John'); // Initially assign values to object of class.
echo $Teacher;

// output is

// Catchable fatal error: Object of class Teacher could not be converted to string in C:\wamp64\www\magic-functions\toString.php on line 13

?>

12. __invoke()

When an object of the class treated as a function, the magic method __invoke() is there to handle the situation.

It is important to note that this feature is only available in PHP 5.3.0 and after.

<?php
class Teacher
{
    public $teacherName;

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

    public function __invoke() {
        echo 'An object of a class treated as Function.';
    }

}

$Teacher = new Teacher('John'); // Initially assign value to the object of the class.
$Teacher();

// output is

// An object of a class treated as Function.

?>

What if the __invoke() method don't define in the Class. Let's have a look.

<?php
class Teacher
{
    public $teacherName;

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

}

$Teacher = new Teacher('John'); // Initially assign value to the object of the class.
$Teacher();

// output is

//  Fatal error: Uncaught Error: Function name must be a string in C:\wamp64\www\magic-functions\invoke.php on line 14
// Error: Function name must be a string in C:\wamp64\www\magic-functions\invoke.php on line 14
?>

13.__set_state()

This magic method is available in PHP 5.1.0 and after. When called var_export() to export the class code, this method is set automatically to set a specific state for the property of the class.

The method took parameters in the form of an array and the format is the same as ('propertyName' => propertyValue,...).

First of all, Let's have a look when we don't use the set_state() method. This is what happened.

<?php
class Teacher
{
    public $teacherName;
    public $teacherAge;

    public function __construct($teacherName="",  $teacherAge=26)
    {
        $this->teacherName = $teacherName;
        $this->teacherAge  = $teacherAge;
    }

}

$Teacher = new Teacher('John'); // Initially assign value to the object.
var_export($Teacher);

// output is 

// Teacher::__set_state(array( 'teacherName' => 'John', 'teacherAge' => 26, ))

?>

Now set the __set_state() method to the class. Let's try.

<?php
class Teacher
{
    public $teacherName;
    public $teacherAge;

    public function __construct($teacherName="",  $teacherAge=26)
    {
        $this->teacherName = $teacherName;
        $this->teacherAge  = $teacherAge;
    }

    public static function __set_state($array)
    {
        $a = new Teacher();
        $a->name = $array['name'];
        return $a;
    }

}

$Teacher = new Teacher('John'); // Initially assign value to the object.
$Teacher->teacherName = 'Doe';
var_export($Teacher);

// output is 

// Teacher::__set_state(array( 'teacherName' => 'Doe', 'teacherAge' => 26, ))

?>

14. __clone()

Clone means that copy of something. In PHP clone() method used to copy the object of the class. But the copy of the object of a class is not enough and useful. So there is the other scenario which is provided by the __clone() method.

If we define the clone() method in the class of the object cloned, The property and the values can be modified when the cloning is performed onto the object of a class.

<?php
class Teacher
{
    public $teacherName;
    public $teacherAge;

    public function __construct($teacherName="",  $teacherAge=26)
    {
        $this->teacherName = $teacherName;
        $this->teacherAge  = $teacherAge;
    }

    public function __clone()
    {
        echo __METHOD__."An object of the class is cloned.<br>";
    }

}

$Teacher = new Teacher('John'); // Initially assigned.
$Teacher2 = clone $Teacher;

var_dump('Student:');
var_dump($Teacher);
echo '<br>';
var_dump('Student2:');
var_dump($Teacher2);
// output is 


// Teacher::__cloneAn object of the class is cloned.
// C:\wamp64\www\magic-functions\clone.php:23:string 'Student:' (length=8)
// C:\wamp64\www\magic-functions\clone.php:24:
// object(Teacher)[1]
// public 'teacherName' => string 'John' (length=4)
//  public 'teacherAge' => int 26

// C:\wamp64\www\magic-functions\clone.php:26:string 'Student2:' (length=9)
// C:\wamp64\www\magic-functions\clone.php:27:
// object(Teacher)[2]
//  public 'teacherName' => string 'John' (length=4)
//  public 'teacherAge' => int 26

?>

15.__autoload()

This magic function or method tried to autoload the object of the classes. In normal, if you create 2 or 3 or more than 3 objects then you've to load them with include() or required() functions.

For example.

<?php
require_once('Magic/magicClass/magicFileA.php');
require_once('project/magicClass/magicFileB.php');
require_once('project/magicClass/magicFileC.php');


if (Condition1) {
    $a = new objA();
    $b = new objB();
    $c = new objC();

} else if (Condition2) {
    $a = new objectA();
    $b = new objectB();
}
?>

On the other hand, the magic method autoload() having an ability to load them at once with few lines of code. Let's try the above example with __autoload() method.

<?php
function  __autoload($magicFile) {
  $filePath = Magic/Class/{$magicFile}.php”;
  if (is_readable($filePath)) {
      require($filePath);
  }
}

if (Condition1) {
    $a = new objA();
    $b = new objB();
    $c = new objC();

} else if (Condition2) {
    $a = new objectA();
    $b = new objectB();
}
?>

16. __debugInfo()

This magic function is set when the var_dump() method called for the object of the class. It is important to know that this magic method is available in PHP 5.6.0 and after

<?php
class Abc{
    private $propValue;

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

    public function __debugInfo() {
        return [
            'propValue' => $this->propValue * 4 * 2,
        ];
    }
}

var_dump(new Abc(42));

// output is


// C:\wamp64\www\magic-functions\debugInfo.php:16:
// object(Abc)[1]
//   public 'propValue' => int 336
?>

If we don't use the magic function __debugInfo() it prints out all the properties in the object.