PHP Tutorial - PHP Magic Methods






Whenever you see a method name start with a double underscore, it is a "magic" method. PHP reserves all methods starting with __ as magic.

PHP Class Constructor

A constructor is a special method that is called by PHP when you create an instance of the class.

PHP class constructor has the following syntax.

public function __construct(Optional Parameter) {}
<?PHP
   class MyClass { 
     function __construct() { 
       echo "I am being constructed."; 
     } 
   } 
          
   $obj = new MyClass;  
?>

The code above generates the following result.

The class, MyClass , contains a very simple constructor that just displays the message. When the code then creates an object from that class, the constructor is called and the message is displayed.





Example 2

You can pass arguments to constructors, like normal methods.

<?PHP
   class Person { 
     private $_firstName; 
     private $_lastName; 
     private $_age; 
          
     public function __construct( $firstName, $lastName, $age ) { 
       $this-> _firstName = $firstName; 
       $this-> _lastName = $lastName; 
       $this-> _age = $age; 
     } 
   } 
          
   $p = new Person( "James", "Bond", 28 ); 
?>

The Person class contains three private properties and a constructor that accepts three values, setting the three properties to those values.





Example 3

If a class contains a constructor, it is only called if objects are created from that class.

If an object is created from a child class, only the child class's constructor is called.

To make a child class call its parent's constructor call parent::__construct().

<?PHP
class NameTag {
       public $Words;
}

class Book {
       public $Name;

       public function say() {
               print "Woof!\n";
       }

       public function __construct($BookName) {
               print "Creating a Book: $BookName\n";
               $this->Name = $BookName;
       }
}


class ComputerBook extends Book {
       public function say() {
               print "Computer!\n";
       }

       public function __construct($BookName) {
               parent::__construct($BookName);
               print "Creating a computer book\n";
       }
}
?>

It is better to call parent::__construct() first from the constructor of a child class, in order to set up all the parent's properties.

PHP Class Destructors

Destructors are useful for tidying up an object before it's removed from memory.

You create destructor methods in the same way as constructors, except that you use __destruct() rather than __construct() :

function __destruct() { 
    // (Clean up here) 
}   

PHP destructors is called when an object is deleted. The destructor method, __destruct(), takes no parameters.

<?PHP
class Book {
       public $Name;
       public function say() {
               print "Woof!\n";
       }

       public function __construct($BookName) {
               print "Creating a Book: $BookName\n";
               $this->Name = $BookName;
       }
        public function __destruct() {
               print "{$this->Name} is destructing\n";
        }

}
$aBook = new Book("PHP");
?>

The code above generates the following result.

Call parent::__destruct().

The key difference is that you should call parent::__destruct() after the local code for the destruction. For example:

<?PHP
public function __destruct() {
       print "{$this->Name} is no more...\n";
       parent::__destruct();
}
?>

The following code shows how to create Constructors and destructor.

<?php
  class Counter
  {
    private static $count = 0;

    function __construct()
    {
      self::$count++;
    }

    function __destruct()
    {
      self::$count--;
    }

    function getCount()
    {
      return self::$count;
    }
  }

  //create one instance
  $c = new Counter();

  //print 1
  print($c->getCount() . "<br>\n");

  //create a second instance
  $c2 = new Counter();

  //print 2
  print($c->getCount() . "<br>\n");

  //destroy one instance
  $c2 = NULL;

  //print 1
  print($c->getCount() . "<br>\n");
?>


The code above generates the following result.

Deleting Objects

Calling unset() on an object will call its destructor before deleting the object.

Magic method list

PHP allows you to create three " magic " methods that you can use to intercept property and method accesses:

  • __get() is called whenever the calling code attempts to read an invisible property of the object
  • __set() is called whenever the calling code attempts to write to an invisible property of the object
  • __call() is called whenever the calling code attempts to call an invisible method of the object

visible refers to non-existing property or method or private or protected the property or method.

__get()

__get() specifies what to do when loading an unknown property.

For example:

<?PHP
     class Book {
             public $Name;


             public function __get($var) {
                     print "Attempted to retrieve $var and failed...\n";
             }
     }
     $aBook = new Book;
     print $aBook->Price;
?>
Overloading Property Accesses with __get()
<?PHP
            class Car { 
              public function __get( $propertyName ) { 
                echo "The value of '$propertyName' was requested < br / > "; 
                return "blue"; 
              } 
            } 
                  
            $car = new Car; 
            $x = $car->color; 
            echo "The car's color is $x \n";
?>

The code above generates the following result.

__set()

Use __set() method to catch an attempt to set an invisible property to a value, use needs two parameters: the property name and the value to set it to.

It does not need to return a value:

public function __set( $propertyName, $propertyValue ) { 
   // (do whatever needs to be done to set the property value) 
}      

The __set() magic method is called when setting an undefined property.

<?PHP
      class Book {
              public function __set($var, $val) {
                      print("UPDATE $var = '$val';");
              }

      }

      $book = new Book();
      $book ->Price= 1.2;
?>

The code above generates the following result.

__call()

Use __call() to handle calls to nonexistent methods of a class. The method should then return a value (if any) back to the calling code:

public function __call( $methodName, $arguments ) { 
   // (do stuff here) 
   return $returnVal; 
} 

The __call() magic method is called when calling a missing method. Here's an example of __call() in action:

<?PHP
     class Book {
             public function __call($function, $args) {
                     $args = implode(', ', $args);
                     print "Call to $function() with args '$args' failed!\n";
             }
     }

     $aBook = new Book;
     $aBook->nonExistingMethod("foo", "bar", "baz");
?>

The code above generates the following result.

__toString()

__toString() allows you to set a string value for the object.

<?PHP
     class Cat {
             public function __toString() {
                     return "This is a cat\n";
             }
     }

     $c = new Cat;
     print $c;
?>

The code above generates the following result.

Example 5

The following code shows how to create __clone methord.


<?php
  class ObjectTracker
  {
    private static $nextSerial = 0;
    private $id;
    private $name;

    function __construct($name)
    {
      $this->name = $name;
      $this->id = ++self::$nextSerial;
    }

    function __clone()
    {
      $this->name = "Clone of $that->name";
      $this->id = ++self::$nextSerial;
    }

    function getId()
    {
      return($this->id);
    }

    function getName()
    {
      return($this->name);
    }
  }

  $ot = new ObjectTracker("Zeev's Object");
  $ot2 = clone $ot;

  //1 Zeev's Object
  print($ot->getId() . " " . $ot->getName() . "<br>");

  //2 Clone of Zeev's Object
  print($ot2->getId() . " " . $ot2->getName() . "<br>");
?>