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