#native_company# #native_desc#
#native_cta#

Implementing User Defined Interfaces in PHP 5

By Octavia Anghel
on July 17, 2012

Starting with PHP 5 the object model was rewritten to add features and bring PHP in line with languages such as Java and Visual Basic .NET. In this article I’ll discuss interfaces, which is among the most important features in PHP 5. Other important features include visibility, abstract and final classes, methods and additional magic methods. You will learn how to define your own interfaces and how to work with them using different object model mechanisms.

While PHP 5 also comes with a set of predefined interfaces that may help you in understanding and working with interfaces their illustration is beyond the scope of this article. For your reference some of these predefined interfaces are Traversable, Iterator, IteratorAggregate, ArrayAccess, Serializable and Closure.

A PHP interface defines methods that are used define a behavior for an object. Follow these rules when working with PHP interfaces:

* Interfaces do not implement methods.

* Interfaces are not part of a hierarchy of classes.

* Interfaces are not similar to abstract classes.

* A class can implement any number of interfaces.

* The same interface can be implemented by several classes.

* A class that implements an interface must implement the methods defined in the interface.

* A class that implements an interface may not implement its methods if the interface is declared abstract.

* When a class implements an interface automatically the class inherits the constants declared in the interface.

In general this is how you declare an interface:

interface int_name [extends      
                            superint1_name, superint2_name,...]
                         {
                         //int_name interface body
                         }

Where:

* interfaces – the key word

* int_name – the name chosen by the programmer interface

* extends – the key word

* superint1_name, superint2_name – an interface can extend any number of superinterfaces Interfaces that are extended should be separated by a comma.

* interface body – where the programmer declares constants (if any) and defines the methods to be implemented by any class that will extend the interface

Remarks:

* All methods declared in an interface must be public.

* The class implementing the interface must use the exact same method signatures as are defined in the interface.

* A class cannot implement two interfaces that share function names.

* Interfaces may have constants. Interface constants work exactly like class constants except they cannot be overridden by a class/interface that inherits it.

* Before creating an interface you should know where you will implement it in different classes. Changing the interface method signature after it has been implemented (implementation of the methods defined in the interface) requires modification of all classes that implement the interface.

* When a class implements an interface, it must provide an explicit implementation for each method declared within the interface itself.

Creating a simple interface example

Below are a few examples of user defined interfaces. The first example creates an interface that is implemented by two classes to randomize a string. Notice that the MyStringInterface interface contains a public function, getString, containing two arguments representing the interval values between which the randomized string should be found.

Listing: MyStringInterface.php

<?php
interface MyStringInterface
{
    public function getString($var1, $var2);  
}
?>

The MyStringClass class below implements the MyStringInterface interface from above and uses the getString function to randomize a string using the PHP method rand. Notice that the class that implements the interface must use the exact same method signature as is defined in the interface.

Listing: MyStringClass.php

<?php

include_once('MyStringInterface.php');

class StringRandom implements MyStringInterface
{
      public function getString($var1, $var2)
    {
        $string = rand($var1, $var2);
        return $string;
    }                                                   

}
                                                            
?>

Listing: TestMyRandomString.php

<?php

include_once('MyStringClass.php');

echo("Randomized string");
$intnr = new StringRandom();
$n= $intnr->getString(10e16, 10e20).'';
echo base_convert($n, 10, 36);

?>

The output of TestMyRandomString.php script is:

Implementing User Defined Interfaces in PHP 5
Figure 1. Randomizing a String Using a Simple Interface Example

Extend Interfaces

The next example shows how to extend an interface. To extend an interface you use the extend keyword. The extension mechanism is shown below in the MyNumberRandomInterface interface example and extends the MyRandomInterface. When you implement the MyNumberRandomInterface interface you also have to provide a behavior for the function defined to the extended interface. You can see an example in the IntAndStringRandom.php listing below, which implements the MyNumberRandomInterface interface. You can test the extension interface mechanism by using the testMyRandom.php PHP script. The script creates an instance of IntandStringRandom class and outputs the randomized string and number based on each corresponding method declared to that class.

Listing: MyRandomInterface.php

<?php
interface MyRandomInterface
{
    public function getString($var1, $var2);  
}
?>

Listing: MyNumberRandomInterface.php

<?php

include_once('MyRandomInterface.php');

interface MyNumberRandomInterface extends MyRandomInterface
{
    public function getNumber();  
}
?>

Listing: IntAndStringRandom.php

<?php

include_once('MyNumberRandomInterface.php');

class IntAndStringRandom implements MyNumberRandomInterface
{
  public function getString($var1, $var2)
    {
        $string = rand($var1, $var2);
        return $string;
    }   
               
  public function getNumber(){

    $number = rand(100,500);
     return $number;
    }                               

}
?>

Listing: TestMyRandom.php

<?php

include_once('IntAndStringRandom.php');

$test = new IntAndStringRandom();

echo("String");
echo $test->getString(10e16, 10e20).'';    

echo("Integer number");
echo $test->getNumber(0,100).'';
?>

The output of extended interfaces is shown below in Figure 2.


user defined interfaces in php 5
Figure 2. Randomizing a String and an Int Using the Interface Extend Mechanism

Multiple extension interfaces

The examples below show, as the name suggests, multiple extension interfaces. This can be seen in the MyCharRandomInterface interface that extends the MyRandomInterface and MyNumberRandomInterface. Again, when you implement the MyStringRandomInterface interface you have to provide a behavior for each function defined in each extended interfaces. You can see that behavior in the IntCharAndStringRandom.php listing, which implements the MyCharRandomInterface interface. And again you can test the multiple extension interfaces mechanism with the testMyRandom.php PHP script. In this case the script creates an instance of IntCharAndStringRandom class and outputs the randomized string, number and char based on the corresponding methods declared for that class:

Listing: MyRandomInterface.php

<?php
interface MyRandomInterface
{
    public function getString($var1, $var2);  
}
?>

Listing: MyNumberRandomInterface.php

<?php

interface MyNumberRandomInterface
{
    public function getNumber();  
}
?>

Listing: MyCharRandomInterface.php

<?php

include_once('MyRandomInterface.php');
include_once('MyNumberRandomInterface.php');

interface MyCharRandomInterface extends MyRandomInterface, MyNumberRandomInterface
{
    public function getChar();  
}
?>

Listing: IntCharAndStringRandom.php

<?php

include_once('MyCharRandomInterface.php');

class IntCharAndStringRandom implements MyCharRandomInterface
{   
  public function getString($var1, $var2)
    {
        $string = rand($var1, $var2);
        return $string;
    }   

  public function getNumber()
    {
        $number = rand(100,4000);
        return $number;
    }                  

  public function getChar(){

    $chars = 'bcdfghjklmnprstvwxzaeiou';
     $ch = $chars[mt_rand(0, 18)];
     return $ch;
    }  
}                          
?>

Listing: TestMyRandom.php

<?php

include_once('IntCharAndStringRandom.php');

$test = new IntCharAndStringRandom();

echo("String");
echo $test->getString(10e16, 10e20).'';    

echo("Integer number");
echo $test->getNumber(0,100).'';  

echo("Character");
echo $test->getChar().'';
?>

The output of multiple extension interfaces is shown below in Figure 3.


user defined interface in php 5

Figure 3. Randomizing a String and an Int Using the Interface Extend Mechanism

Overloading

Overloading in PHP means to dynamically “create” properties and methods. Overloading methods are invoked when interacting with properties or methods that have not been declared or are not visible in the current scope. The next application shows how to overload the getNumber method using different number of arguments. The _call() PHP method takes as its first argument the getNumber() method, and as its second argument the number of arguments used in the getNumber() method. In this example you will use two argument sets in the TestMyRandom.php script that call the getNumber() method.

Note that all overloading methods must be defined as public.

Listing: MyRandomInterface.php

<?php
interface MyRandomInterface
{
    function __call($method, $arguments);
}
?>

Listing: MyRandomClass.php

<?php

include_once('MyRandomInterface.php');

class IntRandom implements MyRandomInterface
{
  
    function __call($method, $arguments) {

            if($method == "getNumber" && count($arguments) == 0) {
               return rand();
        }

            if($method == "getNumber" && count($arguments) == 2) {
               return rand($arguments[0],$arguments[1]);
        }

        return -1;
    }                                                  

}

class FloatRandom implements MyRandomInterface
{
  function __call($method, $arguments) {
            if($method == "getNumber" && count($arguments) == 0) {
           return mt_rand()/100;
        }

            if($method == "getNumber" && count($arguments) == 2) {
           return mt_rand($arguments[0],$arguments[1])/100;
        }

        return -1;
    }
 
}
?>

Listing: TestMyRandom.php

<?php

include_once('MyRandomClass.php');

echo("Integer number");
$intnr = new IntRandom();
echo $intnr->getNumber(0,100).'';

echo("Float number");
$floatnr = new FloatRandom();
echo $floatnr->getNumber(1,1000);

?>

The output of overloading getNumber() method is shown below in Figure 4.


user defined interface php 5

Figure 4. Rand an Int and a Float Using the Overloading Method Mechanism

Default and Override

The last example shows how to override the getNumber() method using the MyRandomClass. The MyRandomClass contains the IntRandom and FloatRandom classes that extend the IntDefaultRandom and FloatDefaultRandom default classes.

Listing: MyRandomInterface.php

<?php
interface MyRandomInterface
{
    public function getNumber($var1, $var2);  
}
?>

Listing: MyDefaultRandomClass.php

<?php

include_once('MyRandomInterface.php');

class IntDefaultRandom implements MyRandomInterface
{
  public function getNumber($var1, $var2)
    {
        $number = rand($var1, $var2);
        return $number;
    }                                                   
}

class FloatDefaultRandom implements MyRandomInterface
{
   
  public function getNumber($var1, $var2)
    {
        $number = mt_rand($var1, $var2)/100;
        return $number;
    }

}
?>

Listing: MyRandomClass.php

<?php

include_once('MyDefaultRandomClass.php');

class IntRandom extends IntDefaultRandom
  {
  
  }

class FloatRandom extends FloatDefaultRandom
  {      

  }
?>

Listing: TestMyRandom.php

<?php

include_once('MyRandomClass.php');

echo("Integer number");
$intnr = new IntRandom();
echo $intnr->getNumber(0,100).'';

echo("Float number");
$floatnr = new FloatRandom();
echo $floatnr->getNumber(1,1000);

?>

The output that results from using the default and overriding getNumber() methods is shown below in Figure 5.


user defined interface php 5
Click here for larger image

Figure 5. Randomize an Int and a Float Using the Method Override Mechanism

Conclusion

In this article you have learned how to define your own interfaces in PHP 5. You also have seen how to extend an interface, how to use multiple extension interfaces, how to overload a method declared in an interface and how to override a method declared in an interface.