phprepository-patternirepository

Can't use superclass in Repository implementation in PHP


I'm trying to implement very basic Repository pattern in PHP.

Let's assume I need a common interface to handle common Entity storage:

<?php

interface IRepository
{
    public function persist(Entity $entity);
    // reduced code for brevity
}

Now I build entities types hierarchy:

<?php

abstract class Entity
{
    protected $id;

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

Here's the Post class:

<?php

class Post extends Entity
{
    private $title;

    private $body;
}

Now I would like to use PDO-supported databases to store posts:

<?php

use PDO;

abstract class DatabaseRepository implements IRepository
{
    protected $pdo;

    protected $statement;

    public function __construct(PDO $pdo)
    {
        $this->pdo = $pdo;
    }
}

And now I try to implement IRepository interface

<?php

class PostRepository extends DatabaseRepository
{

    // I have an error here 
    //  Fatal error: Declaration of PostRepository::persist(Post $post) must be compatible with IRepository::persist(Entity $entity) 
    public function persist(Post $post)
    {
    }
}

As you can see this throws fatal error. Using type hinting in PostRepository::persist() I guarantee that I use Entity child object to fulfill IRepository requirements. So why this error is thrown?


Solution

  • As I commented you are looking for generics. For now it isn't possible like JAVA or C# it is however in HHVM

    For PHP the rfc is still in draft status. https://wiki.php.net/rfc/generics

    So if you really want to do it, you either create a more generic interface with some type checking or make Post a subclass of Entity or both a subclass of another parent (this however will generate strict warnings).