更新:PHP 7.4は、この質問で提起された主要な問題に対処する共分散と反変性をサポートするようになりました。
PHP 7で戻り値の型のヒントを使用する際に問題が発生しました。私の理解では、ヒント: self
とは、実装クラスがそれ自体を返すことを意図していることを意味します。したがって: self
、インターフェイスでそれを示すために使用しましたが、実際にインターフェイスを実装しようとすると、互換性エラーが発生しました。
以下は、私が遭遇した問題の簡単なデモンストレーションです。
interface iFoo
{
public function bar (string $baz) : self;
}
class Foo implements iFoo
{
public function bar (string $baz) : self
{
echo $baz . PHP_EOL;
return $this;
}
}
(new Foo ()) -> bar ("Fred")
-> bar ("Wilma")
-> bar ("Barney")
-> bar ("Betty");
期待される出力は次のとおりです。
フレッドウィルマバーニーベティ
私が実際に得るものは次のとおりです。
PHPの致命的なエラー:Foo :: bar(int $ baz)の宣言:FooはiFoo :: bar(int $ baz)と互換性がある必要があります:7行目のtest.phpのiFoo
重要なのは、FooはiFooの実装であり、私が知る限り、実装は特定のインターフェイスと完全に互換性があるはずです。おそらく、インターフェイスまたは実装クラスのいずれか(または両方)を変更して、を使用する代わりに名前でインターフェイスのヒントを返すことでこの問題を修正できますself
が、意味的にself
は「メソッドを呼び出したばかりのクラスのインスタンスを返す」という意味です"。したがって、それをインターフェースに変更することは、理論的には、呼び出されたインスタンスが返されることを意図しているときに、インターフェースを実装する何かのインスタンスを返すことができることを意味します。
これはPHPの見落としですか、それとも意図的な設計上の決定ですか?前者の場合、PHP 7.1で修正される可能性はありますか?そうでない場合、チェーンのためにメソッドを呼び出したばかりのインスタンスを返すことをインターフェースが期待していることを示唆する正しい戻り方法は何ですか?