Why we use interface class in php


PHP - What are Interfaces?

Interfaces allow you to specify what methods a class should implement.

Interfaces make it easy to use a variety of different classes in the same way. When one or more classes use the same interface, it is referred to as "polymorphism".

Interfaces are declared with the interface keyword:

Syntax

interface InterfaceName {
  public function someMethod1();
  public function someMethod2($name, $color);
  public function someMethod3() : string;
}
?>


PHP - Interfaces vs. Abstract Classes

Interface are similar to abstract classes. The difference between interfaces and abstract classes are:

  • Interfaces cannot have properties, while abstract classes can
  • All interface methods must be public, while abstract class methods is public or protected
  • All methods in an interface are abstract, so they cannot be implemented in code and the abstract keyword is not necessary
  • Classes can implement an interface while inheriting from another class at the same time

PHP - Using Interfaces

To implement an interface, a class must use the implements keyword.

A class that implements an interface must implement all of the interface's methods.

Example

interface Animal {
  public function makeSound();
}

class Cat implements Animal {
  public function makeSound() {
    echo "Meow";
  }
}

$animal = new Cat();
$animal->makeSound();
?>

Try it Yourself »

From the example above, let's say that we would like to write software which manages a group of animals. There are actions that all of the animals can do, but each animal does it in its own way.

Using interfaces, we can write some code which can work for all of the animals even if each animal behaves differently:

Example

// Interface definition
interface Animal {
  public function makeSound();
}

// Class definitions
class Cat implements Animal {
  public function makeSound() {
    echo " Meow ";
  }
}

class Dog implements Animal {
  public function makeSound() {
    echo " Bark ";
  }
}

class Mouse implements Animal {
  public function makeSound() {
    echo " Squeak ";
  }
}

// Create a list of animals
$cat = new Cat();
$dog = new Dog();
$mouse = new Mouse();
$animals = array($cat, $dog, $mouse);

// Tell the animals to make a sound
foreach($animals as $animal) {
  $animal->makeSound();
}
?>

Try it Yourself »

Example Explained

Cat, Dog and Mouse are all classes that implement the Animal interface, which means that all of them are able to make a sound using the makeSound() method. Because of this, we can loop through all of the animals and tell them to make a sound even if we don't know what type of animal each one is.

Since the interface does not tell the classes how to implement the method, each animal can make a sound in its own way.



What Is a PHP Interface?

A PHP interface defines a contract which a class must fulfill. If a PHP class is a blueprint for objects, an interface is a blueprint for classes. Any class implementing a given interface can be expected to have the same behavior in terms of what can be called, how it can be called, and what will be returned.

In a previous article, I talked about PHP classes. Building on that, today we will talk about interfaces.

PHP Interface Basics

For an example of PHP Interface basics, we will consider "something that vocalizes". In the real world, this could be a bird ("tweets"), a dog ("barks"), a cat ("meows"), or a human ("sings"). The details of vocalization are specific to each type, but each can vocalize.

We could describe this as follows:

interface Vocalizer
{
    public function vocalize(string $message): string;
}

What we are saying above is: given a string $message, vocalize() will return what is heard as a string.

Now, an interface doesn't do anything on its own. It does, however, act as a PHP type. This means you can type hint on it as an argument, or even return something of that type from a function or method.

To create something of that type, we need to have an implementation available. Classes can implement an interface:

class Bird implements Vocalizer
{
    public function vocalize(string $message): string
    {
        return sprintf('%s', $message);
    }
}

Let's say we have a function as follows:

function prepareMessage(string $message, Vocalizer $vocalizer): string
{
    return $vocalizer->vocalize($message);
}

The above function can be called with any $vocalizer that implements Vocalizer:

$chickadee = new Bird();
echo prepareMessage('a song', $chickadee); // "a song"

Inheritance and Substitution

In a nutshell, interfaces give us a way to provide features without requiring class inheritance. This can be really useful for adapting existing classes to work in other contexts.
As an example, let's say we had a Bird class already that did not implement Vocalizer, but we had essentially equivalent functionality via a method tweet():

class Bird
{
    public function tweet(string $message): string
    {
        return sprintf('%s', $message);
    }
}

We could do one of two things to make this class a Vocalizer at this point, while keeping all existing functionality.

First, we could update the class to directly implement the Vocalizer interface:

class Bird implements Vocalizer
{
    public function vocalize(string $message): string
    {
        return $this->tweet($message);
    }

    public function tweet(string $message): string
    {
        return sprintf('%s', $message);
    }
}

Alternately, we could create an extension of Bird that implements Vocalizer:

class VocalizingBird extends Bird implements Vocalizer
{
    public function vocalize(string $message): string
    {
        return $this->tweet($message);
    }
}

Because this latter is an extension of Bird, it fulfills the Bird type for typehints; because it also implements Vocalizer, it also fulfills that type. You could also accomplish the above via an anonymous class implementation:

$bird = new class extends Bird implements Vocalizer {
    public function vocalize(string $message): string
    {
        return $this->tweet($message);
    }
};

This leads us to a key rationale for using interfaces: the ability to substitute one type for another.

Five Principles for Object-Oriented Programming

When performing object-oriented programming, there is a set of five core design principles that are recommended for creating flexible, maintainable architectures known as the SOLID principles:

•    Single-responsibility principle
•    Open-closed principle
•    Liskov substitution principle
•    Interface segregation principle
•    Dependency inversion principle

Dependency Inversion Principle

What I want to point attention to here is the dependency inversion principle.

The dependency inversion principle states that we should depend on abstractions, not implementations. What does that mean?

If we are only worried about vocalization, we should not need to worry about whether or not we have a Bird, a Human, or an Animal. We should worry about whether or not we have something capable of vocalization. 

Interfaces allow us to define these capabilities, and then allow our code to typehint against those capabilities, and not a more specific type. This in turn allows us to substitute different types when they fulfill the contract defined by the interface.

Common Mistake When Performing Object-Oriented Programming

One common mistake when beginning to perform object-oriented programming is to create a strict inheritance tree: a base class, and then subtypes of that base class, and then implementations of those subtypes, and so on. 

This can lead to creating a class that technically has a dozen or more different behaviors, but which is only used for one of them. By splitting these behaviors out into different interfaces, we can create classes that implement only specific behaviors, and use them wherever those behaviors are needed.

What Can We Define In an PHP Interface?

Now that we have a basic idea of what an interface is, why we might use one, and how we can implement one? What exactly can we define in an interface?

Interfaces in PHP are limited to:
•    Publicly visible methods.
•    Publicly visible constants.

In our previous article on PHP classes, we noted that visibility is a more advanced topic. It still is, but we can cover some basics. In a nutshell, visibility helps detail what can use the functionality, and where. Something that has public visibility can be accessed both within class methods, as well as from instances. What is meant by the latter? In the following:

$chickadee = new Bird();

$chickadee is an instance.

Digression: Class Constants

In the article on classes we didn't cover class constants. A class constant is just like a normal PHP constant in that it details a value that, well, remains constant. It's a value that cannot be reassigned later. To declare a class constant, you use the const keyword within your class declaration, and optionally a visibility operator (like properties and methods, visibility defaults to public):

class Bird
{
    public const TAXONOMY_CLASS = 'aves';
}

You then refer to using the class name and constant name, separated by:

$taxonomy = Bird::TAXONOMY_CLASS;

A class constant can be any scalar type, or an array, as long as no members of the array are objects. They can even refer to other constants if needed.

By convention, constant names are usually in ALL UPPERCASE, using underscore separators.

Constants defined on an interface are inherited by all implementations.

When defining a method on an interface, you omit the body and its braces, and instead end the declaration with a semi-colon (;); you are defining a signature only. These indicate what the implementation must define in order to be valid.

We've already seen a method definition previously, when we defined a vocalize() method on our Vocalizer interface:

public function vocalize(string $message): string;

As such, any implementation must define this method, and be compatible. They can add more arguments — but only if those arguments are optional. That's the only way they can differ.

Ability to Implement Multiple Inheritance

One feature some languages offer is multiple inheritance. This feature allows an object to extend multiple other types, and thus fulfill them all. As an example, a Horse class could extend both an Animal and a Vehicle class.

PHP does not offer multiple inheritance, at least not directly. What it does provide, however, is the ability to implement multiple interfaces. This can be useful particularly when you want to describe a subset of features a particular class provides within a given context. 

Example of Implementing Multiple Interfaces

As an example, the laminas/laminas-cache package defines a variety of interfaces describing storage adapter capabilities, including FlushableInterface, OptimizableInterface, ClearByPrefixInterface, TaggableInterface, etc. Individual adapters are all storage adapters, but they can indicate they have other capabilities by implementing these interfaces.

To implement multiple interfaces, you provide a comma-separated list of interfaces following the implements keyword when declaring your class:

class MyCustomStorageAdapter extends AbstractAdapter implements
    ClearByStorageInterface,
    FlushableInterface,
    OptimizableInterface,
    TaggableInterface
{
    // . . .
}

An instance of this class would then fulfill typehints against each of these interfaces.

Naming PHP Interfaces

How should you name your interface? Generally speaking, name it based on the behaviors it describes. Per our example, we were defining something that vocalizes, so we named the interface Vocalizer.

This can be difficult to figure out, particularly if you extract an interface from a class you've previously defined, where the logical name is already the name of an existing class (e.g., you might want to define a Logger interface, but a Logger class already exists). 

Sometimes the naming difficulty is due to having a team of developers from different backgrounds or countries (e.g., some members of the team might not share the same native language). As such, many projects use an Interface suffix to simplify the naming decision, as well as to call out which class files in a project are contracts versus implementations.

You and your team should decide which approach makes most sense for you!

Next Steps

PHP interfaces provide reusable types detailing specific behaviors that your application can consume. In particular, they allow you to create classes that have known, expected behaviors that fit within your own application architecture. PHP interfaces also allow you to substitute different implementations, regardless of normal class inheritance, giving you more flexibility in how your structure your applications.

This write-up is hardly exhaustive. Zend by Perforce has a number of resources to help you learn more about object-oriented programming in the PHP language. Check out our training options here.

GET FREE TRAINING

Why should we use interface in PHP?

PHP - What are Interfaces? Interfaces allow you to specify what methods a class should implement. Interfaces make it easy to use a variety of different classes in the same way. When one or more classes use the same interface, it is referred to as "polymorphism".

WHAT IS interface and why it is used in PHP?

A PHP interface defines a contract which a class must fulfill. If a PHP class is a blueprint for objects, an interface is a blueprint for classes. Any class implementing a given interface can be expected to have the same behavior in terms of what can be called, how it can be called, and what will be returned.

Why should we use interface?

Interfaces are useful for the following: Capturing similarities among unrelated classes without artificially forcing a class relationship. Declaring methods that one or more classes are expected to implement. Revealing an object's programming interface without revealing its class.

Why do we use abstract class and interface in PHP?

In PHP you can use interfaces define common functionality that is provided my similar classes. Abstract classes are used to define base classes that provide common functionality. Despite interfaces and abstract classes are somewhat related, they are not the same.