The original post: /r/php by /u/mwargan on 2024-10-08 20:55:04.

Is there an alternative for declaring interfaces that allow an instance of the inheriting class as a method parameter?

This example fails as its written. Removing self from the method parameter interface declaration, the code works. This seems strange as it should fail with the same type exception, because the return type is also self.

Playground: https://php-play.dev/?c=DwfgDgFmBQD0sAICmAPAhgWzAGyQgxgPYAmS0AlgHYAuSATgGZr54BihhAkjfUywgG9oCEQjABXAEbZy%2BBAGdqaarIQNxlfCsKU1dQhgCClAJ7UIVAOYAKRXSsAfeUmwMHaOnTQmEAEmLKaACUAFwKLgwA3NAAvtDQ%2BNho8vIIAEIeCORYuBhINKnsXDyMzHhComJSMnKKyqrqmtq6DPpGpuZWttT2lJZOEe6e3n4BSqHhroLClbNZDAjW-oFZlHWaSIQLzq5B03NzdEjU4nS6y0rRBwhxM3PkC9bk8gD6Hl4mS2PBexXXokcTmcEJQkAB3SYML6BADaAAYALpBK4HW7XQGnXSgiE7KEXYIokRokSNLTkHQIF4vaiEADKPS6vzuswxwIA5AB1Qh0bDENmEm6xeJIfAQQjpDwhEKtAzGMwWPrWNkACRc2EIbORQA&v=8.3&f=html

interface FooInterface {
 public static function fromAnything(string|self|array $data): self;
}

class Bar implements FooInterface {
 public static function fromAnything(string|self|array $data): self {
 // stuff
 return new self($data);
 }
}

echo Bar::fromAnything('Hello'); // Fails with a method parameter type error

It seems in PHP8.3 (and maybe others), the types in the class are actually resolved to php fromAnything(string|FooInterface|array $data): Bar; Whereas I’d expect it to be either FooInterface or Bar, but not both.