I've made this simple example to show what i'm trying to do:
<?php
interface UserManagement
{
public function createUser(object $user): ?string;
}
class User
{
public $id;
public $username;
public $email;
}
//-----------------------------------------------------------//
class MyUser extends User
{
}
class MyUserManagement implements UserManagement
{
public function createUser(MyUser $user): ? string
{
}
}
This contains an abstract interface definition for user-management and also a base class for a user-object. In the second part it uses that definitions.
When i try to execute the code, the parser bails out:
PHP Fatal error: Declaration of MyUserManagement::createUser(MyUser $user): ?string
must be compatible with UserManagement::createUser(object $user): ?string
in ./test.php on line 24
I don't understand why it fails, as the definition look pretty equal to me.
CodePudding user response:
When you implement an interface your functions should have the same type of parameters. In this case the createUser function of interface have (object $user), and the function in your class have (MyUser $user).
CodePudding user response:
That 's the normal behavior in PHP. When you define a method in an interface or in a superclass all inherited classes must implement exactly this signature. You can not override the provided method signature.
Although MyUser
is of type object
the signature in your UserManagement
interface defines the parameter as object
and not as MyUser
. Because MyUserManagement
implements the UserManagement
interface, the type hint for the $user
parameter has to be object
.
It is not possible to override the type hint.
Best practice out there is to define type hints in interfaces or superclasses only. Inherited classed do not need a type hint in that case.