AGGIORNAMENTO : PHP 7.4 ora supporta covarianza e controvarianza che risolvono il problema principale sollevato in questa domanda.
Ho riscontrato un problema con l'utilizzo dell'hinting del tipo di ritorno in PHP 7. La mia comprensione è che hinting : self
significa che si intende che una classe di implementazione ritorni da sola. Pertanto ho usato : self
nelle mie interfacce per indicarlo, ma quando ho provato a implementare effettivamente l'interfaccia ho ricevuto errori di compatibilità.
Quanto segue è una semplice dimostrazione del problema che ho riscontrato:
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");
L'output previsto era:
Fred Wilma Barney Betty
Quello che ottengo effettivamente è:
Errore irreversibile PHP: Dichiarazione di Foo :: bar (int $ baz): Foo deve essere compatibile con iFoo :: bar (int $ baz): iFoo in test.php alla riga 7
Il fatto è che Foo è un'implementazione di iFoo, quindi per quanto ne so l'implementazione dovrebbe essere perfettamente compatibile con l'interfaccia data. Presumibilmente potrei risolvere questo problema modificando l'interfaccia o la classe di implementazione (o entrambi) per restituire un suggerimento sull'interfaccia per nome invece di utilizzarlo self
, ma la mia comprensione è che semanticamente self
significa "restituire l'istanza della classe su cui hai appena chiamato ". Pertanto, cambiarlo nell'interfaccia significherebbe in teoria che potrei restituire qualsiasi istanza di qualcosa che implementa l'interfaccia quando il mio intento è che l'istanza invocata sia ciò che verrà restituito.
È una svista in PHP o è una decisione di progettazione deliberata? Se è il primo, c'è qualche possibilità di vederlo corretto in PHP 7.1? In caso contrario, qual è il modo corretto di restituire suggerendo che la tua interfaccia si aspetta che tu restituisca l'istanza su cui hai appena chiamato il metodo per il concatenamento?