0

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?

erop
  • 1,510
  • 1
  • 14
  • 27
  • The error seems pretty clear. `persist(Post $post) ` has to be `persist(Entity $entity) `. – Jonnix Mar 30 '17 at 09:39
  • You are looking for generics, it works like [this](http://stackoverflow.com/questions/16131410/implementing-methods-from-an-interface-but-with-different-parameters) in JAVA. I'm not sure if there is a solution for PHP, I know HHVM has. I'll have a look – Timmetje Mar 30 '17 at 09:43

1 Answers1

1

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).

Community
  • 1
  • 1
Timmetje
  • 7,641
  • 18
  • 36
  • Thank you, @Timmetje , for the complete answer. But isn't good enough to "make Post a subclass of Entity" to extend Post from Entity as shown above? – erop Mar 30 '17 at 12:11
  • You can do this because then Post would be an instance of Entity, but PHP will throw strict warnings. You should play around with it, to see if it fits what you need. – Timmetje Mar 30 '17 at 13:14
  • Thanks again, @Timmetje! – erop Mar 30 '17 at 13:31