Pour développer la réponse de Berry, le fait de définir le niveau d'accès sur protected permet d'utiliser __get et __set avec des propriétés explicitement déclarées (au moins en cas d'accès en dehors de la classe) et la vitesse étant considérablement plus lente, je vais citer un commentaire d'une autre question sur ce sujet et faites un cas pour l'utiliser quand même:
Je suis d'accord que __get est plus lent à une fonction get personnalisée (faisant les mêmes choses), c'est 0,0124455 le temps pour __get () et ce 0,0024445 est pour custom get () après 10000 boucles. - Melsi 23 novembre 12 à 22:32 Meilleures pratiques: méthodes PHP Magic __set et __get
Selon les tests de Melsi, considérablement plus lent est environ 5 fois plus lent. C'est certainement beaucoup plus lent, mais notez également que les tests montrent que vous pouvez toujours accéder à une propriété avec cette méthode 10000 fois, en comptant le temps pour l'itération de la boucle, en environ 1/100 de seconde. Il est considérablement plus lent en comparaison avec les méthodes get et set définies, et c'est un euphémisme, mais dans le grand schéma des choses, même 5 fois plus lent n'est jamais vraiment lent.
Le temps de calcul de l'opération est encore négligeable et ne vaut pas la peine d'être pris en compte dans 99% des applications du monde réel. Le seul moment où cela devrait vraiment être évité, c'est lorsque vous allez réellement accéder aux propriétés plus de 10000 fois en une seule demande. Les sites à fort trafic font quelque chose de vraiment mal s'ils ne peuvent pas se permettre de lancer quelques serveurs supplémentaires pour maintenir leurs applications en marche. Une annonce textuelle sur une seule ligne au pied d'un site à fort trafic où le taux d'accès devient un problème pourrait probablement payer pour une batterie de 1 000 serveurs avec cette ligne de texte. L'utilisateur final ne se demandera jamais ce qui prend si longtemps à charger la page, car l'accès aux propriétés de votre application prend un millionième de seconde.
Je dis cela en tant que développeur issu d'une expérience dans .NET, mais les méthodes get and set invisibles pour le consommateur ne sont pas l'invention de .NET. Ce ne sont tout simplement pas des propriétés sans elles, et ces méthodes magiques sont la grâce salvatrice du développeur PHP pour même appeler leur version de propriétés "propriétés". De plus, l'extension Visual Studio pour PHP prend en charge intellisense avec des propriétés protégées, avec cette astuce à l'esprit, je pense. Je pense qu'avec suffisamment de développeurs utilisant les méthodes magiques __get et __set de cette façon, les développeurs PHP ajusteraient le temps d'exécution pour répondre à la communauté des développeurs.
Edit: En théorie, les propriétés protégées semblaient fonctionner dans la plupart des situations. En pratique, il s'avère que vous voudrez souvent utiliser vos getters et setters lors de l'accès aux propriétés dans la définition de classe et les classes étendues. Une meilleure solution est une classe de base et une interface pour l'extension d'autres classes, vous pouvez donc simplement copier les quelques lignes de code de la classe de base dans la classe d'implémentation. Je fais un peu plus avec la classe de base de mon projet, donc je n'ai pas d'interface à fournir pour le moment, mais voici la définition de classe dépouillée non testée avec la propriété magique obtenant et définissant en utilisant la réflexion pour supprimer et déplacer les propriétés vers un tableau protégé:
class Component {
protected $properties = array();
public function __get($name) {
$caller = array_shift(debug_backtrace());
$max_access = ReflectionProperty::IS_PUBLIC;
if (is_subclass_of($caller['class'], get_class($this)))
$max_access = ReflectionProperty::IS_PROTECTED;
if ($caller['class'] == get_class($this))
$max_access = ReflectionProperty::IS_PRIVATE;
if (!empty($this->properties[$name])
&& $this->properties[$name]->class == get_class()
&& $this->properties[$name]->access <= $max_access)
switch ($name) {
default:
return $this->properties[$name]->value;
}
}
public function __set($name, $value) {
$caller = array_shift(debug_backtrace());
$max_access = ReflectionProperty::IS_PUBLIC;
if (is_subclass_of($caller['class'], get_class($this)))
$max_access = ReflectionProperty::IS_PROTECTED;
if ($caller['class'] == get_class($this))
$max_access = ReflectionProperty::IS_PRIVATE;
if (!empty($this->properties[$name])
&& $this->properties[$name]->class == get_class()
&& $this->properties[$name]->access <= $max_access)
switch ($name) {
default:
$this->properties[$name]->value = $value;
}
}
function __construct() {
$reflected_class = new ReflectionClass($this);
$properties = array();
foreach ($reflected_class->getProperties() as $property) {
if ($property->isStatic()) { continue; }
$properties[$property->name] = (object)array(
'name' => $property->name, 'value' => $property->value
, 'access' => $property->getModifier(), 'class' => get_class($this));
unset($this->{$property->name}); }
$this->properties = $properties;
}
}
Mes excuses s'il y a des bogues dans le code.