Imagine following abstract Interface
interface IDomainRepository {
/**
* Finds a Domain Object by the Id
*
* @param int $id the id of the object
*
* @return IDomainObject the domain object
*/
public function findById($id);
//More than that method...
}
And now a specific Interface which extends from IDomainRepository
interface IUserRepository extends IDomainRepository {
//More than only extending...
}
If i call something like this, i want type hint without extra comment here (because i use this very often).
function foo(IUserRepository $repo) {
$user = $repo->findById(42)
//Typehint User without @var User $user
}
Currently i do it this way:
/**
* Interface IUserRepository
* @method User findById($id)
*/
interface IUserRepository extends {
}
But the "@method" parameter is for hidden magic methods. So this feels wrong. Is there a better solution availible?
Should i don't have a Base Interface, only the specific one (Which means copy & pasting about 20 Method Signatures?
As there is no return type hinting in PHP yet it's most times all about preferences, depending on the IDE used there may be no difference in using an @method
tag or a docblock for an additional method declaration, so....
Note that you don't necessarily have to move the methods (and you most probably don't want to anyways as it would make implementations of IDomainRepository
not require a findById()
method), but you can simply redeclare/overwrite them in your extending interfaces when necessary and supply a proper docblock as shown by @Deele:
interface IUserRepository extends IDomainRepository {
/**
* Finds a User by Id
*
* @param int $id the id of the object
*
* @return IUserRepository the User object
*/
public function findById($id);
}
Personally I would consider that the cleaner approach over using @method
, as it makes it more clear how a concrete implementation of findById()
should behave (by just looking at the code of the method declaration), and that it is expected to be different to the one of the base interface.
On a side note, one day this might also be "compatible" to the covariant return-type hinting proposed in PHP RFC: Return Type Declarations:
// Covariant return-type:
interface Collection {
function map(callable $fn): Collection;
}
interface Set extends Collection {
function map(callable $fn): Set;
}