7.4+ :
Bonne nouvelle, cela sera implémenté dans les nouvelles versions, comme l'a souligné @Andrea. Je vais simplement laisser cette solution ici au cas où quelqu'un voudrait l'utiliser avant la version 7.4.
7,3 ou moins
D'après les notifications que je reçois encore de ce fil de discussion, je pense que de nombreuses personnes ont eu/ont le même problème que moi. Ma solution pour ce cas était de combiner setters + __set
méthode magique à l'intérieur d'un trait afin de simuler ce comportement. Le voici :
trait SettersTrait
{
/**
* @param $name
* @param $value
*/
public function __set($name, $value)
{
$setter = 'set'.$name;
if (method_exists($this, $setter)) {
$this->$setter($value);
} else {
$this->$name = $value;
}
}
}
Et voici la démonstration :
class Bar {}
class NotBar {}
class Foo
{
use SettersTrait; //It could be implemented within this class but I used it as a trait for more flexibility
/**
*
* @var Bar
*/
private $bar;
/**
* @param Bar $bar
*/
protected function setBar(Bar $bar)
{
//(optional) Protected so it wont be called directly by external 'entities'
$this->bar = $bar;
}
}
$foo = new Foo();
$foo->bar = new NotBar(); //Error
//$foo->bar = new Bar(); //Success
Explication
Tout d'abord, définissez bar
comme une propriété privée. PHP va donc lancer __set
automatiquement .
__set
vérifiera s'il existe un setter déclaré dans l'objet courant ( method_exists($this, $setter)
). Sinon, il ne fera que fixer sa valeur comme il le ferait normalement.
Déclarez une méthode setter (setBar) qui reçoit un argument de type hinted ( setBar(Bar $bar)
).
Tant que PHP détecte que quelque chose qui n'est pas Bar
est passée au setter, cela déclenchera automatiquement une erreur fatale : Erreur de Type Non Rattrapée : Argument 1 passé à Foo::setBar() doit être une instance de Bar, instance de NotBar donnée
1 votes
Pas à ma connaissance. Cependant, d'une manière générale cualquier Les contraintes sur la valeur d'une propriété devraient de toute façon être effectuées par un setter. Puisque le setter peut facilement avoir un typehint pour l'argument "value", vous êtes prêt à partir.
0 votes
De nombreux frameworks utilisent protégé attributs (principalement pour les contrôleurs). Pour ces cas en particulier, ce serait très utile.