7.4+:
Buenas noticias que se implementará en los nuevos lanzamientos, como señaló @Andrea. Dejaré esta solución aquí en caso de que alguien quiera usarla antes de 7.4
7.3 o menos
Según las notificaciones que todavía recibo de este hilo, creo que muchas personas han tenido el mismo problema que yo. Mi solución para este caso fue combinar setters + __set
método mágico dentro de un rasgo para simular este comportamiento. Aquí está:
trait SettersTrait
{
public function __set($name, $value)
{
$setter = 'set'.$name;
if (method_exists($this, $setter)) {
$this->$setter($value);
} else {
$this->$name = $value;
}
}
}
Y aquí está la demostración:
class Bar {}
class NotBar {}
class Foo
{
use SettersTrait;
private $bar;
protected function setBar(Bar $bar)
{
$this->bar = $bar;
}
}
$foo = new Foo();
$foo->bar = new NotBar();
Explicación
En primer lugar, defina bar
como una propiedad privada para que PHP se __set
transmita automáticamente .
__set
comprobará si hay algún setter declarado en el objeto actual ( method_exists($this, $setter)
). De lo contrario, solo establecerá su valor como lo haría normalmente.
Declare un método de establecimiento (setBar) que recibe un argumento con sugerencia de tipo ( setBar(Bar $bar)
).
Siempre que PHP detecte que Bar
se está pasando algo que no es una instancia al establecedor, se activará automáticamente un Error fatal: Error de tipo no detectado: El argumento 1 pasado a Foo :: setBar () debe ser una instancia de Bar, instancia de NotBar dada