Я пытаюсь реализовать очень простой шаблон репозитория в PHP.
Давайте предположим, что мне нужен общий интерфейс для обработки общего хранилища сущностей:
<?php
interface IRepository
{
public function persist(Entity $entity);
// reduced code for brevity
}
Теперь я строю иерархию типов объектов:
<?php
abstract class Entity
{
protected $id;
protected function getId()
{
return $this->id;
}
}
Вот класс Post:
<?php
class Post extends Entity
{
private $title;
private $body;
}
Теперь я хотел бы использовать базы данных с поддержкой PDO для хранения сообщений:
<?php
use PDO;
abstract class DatabaseRepository implements IRepository
{
protected $pdo;
protected $statement;
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
}
И теперь я пытаюсь реализовать интерфейс IRepository
<?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)
{
}
}
Как видите, это приводит к фатальной ошибке. Используя подсказку типа в PostRepository :: persist (), я гарантирую, что использую дочерний объект Entity для выполнения требований IRepository. Так почему эта ошибка выбрасывается?
Как я уже говорил, вы ищете дженерики. На данный момент это не возможно, как ДЖАВА или же C # однако в HHVM
Для PHP RFC все еще находится в черновом состоянии.
https://wiki.php.net/rfc/generics
Так что, если вы действительно хотите это сделать, вы можете создать более общий интерфейс с некоторой проверкой типов или сделать Post
подкласс Entity
или оба подкласса другого родителя (однако это будет генерировать строгие предупреждения).
Других решений пока нет …