DEV Community

Cover image for PHP Interfaces and Type Hinting
Kenta Takeuchi
Kenta Takeuchi

Posted on • Originally published at bmf-tech.com

PHP Interfaces and Type Hinting

This article was originally published on bmf-tech.com.

Overview

This article is part of the PHP Advent Calendar 2018. (Posted a bit earlier)

Interfaces not only serve as a "contract" to ensure method implementation, but they also allow implementations to depend on abstractions through type hinting, making it easier to switch implementations.

Defining and Implementing Interfaces

Basic definition and implementation of an interface.

<?php
interface Action
{
    public function say();
}

class Superman implements Action
{
    public function say()
    {
        echo "Hello World";
    }
}

$obj = new Superman();
$obj->say();
Enter fullscreen mode Exit fullscreen mode

Separation of Functionality and Implementation with Interfaces

Specifying an interface type with type hinting allows for flexibility in implementation.

<?php
interface HeroAction
{
    public function say();
}

class Superman implements HeroAction
{
    public function say()
    {
        echo "I'm a Superman";
    }
}

class Human
{
    public function say()
    {
        echo "I'm a Human";
    }
}

class Bot
{
    public function do(HeroAction $heroAction) // Specify interface type in argument
    {
        $heroAction->say();
    }
}

$superMan = new SuperMan();
$human = new Human();
$bot = new Bot();

$bot->do($superMan); // I'm a Superman
$bot->do($human); // PHP Fatal error:  Uncaught TypeError: Argument 1 passed to Bot::do() must implement interface HeroAction, instance of Human given, called in ....
Enter fullscreen mode Exit fullscreen mode

Switching from Superman to Hyperman implementation.

<?php
interface HeroAction
{
    public function say();
}

// class Superman implements HeroAction
// {
//     public function say()
//     {
//         echo "I'm a Superman";
//     }
// }

class Hyperman implements HeroAction
{
    public function say()
    {
        echo "I'm a Hyperman";
    }
}

class Human
{
    public function say()
    {
        echo "I'm a Human";
    }
}

class Bot
{
    public function do(HeroAction $heroAction) // Specify interface type in argument
    {
        $heroAction->say();
    }
}

// $superMan = new SuperMan();
$hyperMan = new HyperMan();
$human = new Human();
$bot = new Bot();

// $bot->do($superMan); // I'm a Superman
$bot->do($hyperMan); // I'm a Hyperman
$bot->do($human); // PHP Fatal error:  Uncaught TypeError: Argument 1 passed to Bot::do() must implement interface HeroAction, instance of Human given, called in ....
Enter fullscreen mode Exit fullscreen mode

If the do method of the Bot class depended on the Superman class instead of an interface, switching implementations would be more cumbersome.

class Bot
{
    public function do(Superman $superman) // Specify interface type in argument
    {
        $superman->say();
    }
}
Enter fullscreen mode Exit fullscreen mode

References

Top comments (0)