Quand et pourquoi devrais-je utiliser des fonctions et des variables public
, private
et protected
dans une classe? Quelle est la différence entre eux?
Exemples:
// Public
public $variable;
public function doSomething() {
// ...
}
// Private
private $variable;
private function doSomething() {
// ...
}
// Protected
protected $variable;
protected function doSomething() {
// ...
}
Tu utilises:
public
portée pour rendre cette variable/fonction disponible à partir de n’importe où, des autres classes et instances de l’objet.
private
scope lorsque vous souhaitez que votre variable/fonction soit visible uniquement dans sa propre classe.
protected
scope lorsque vous souhaitez rendre votre variable/fonction visible dans toutes les classes qui étendent la classe actuelle, y compris la classe parente.
More: (Pour une information complète)
Lorsque vous déclarez une méthode (fonction) ou une propriété (variable) en tant que public
, vous pouvez accéder à ces méthodes et propriétés de la manière suivante:
Exemple:
<?php
class GrandPa
{
public $name='Mark Henry'; // A public variable
}
class Daddy extends GrandPa // Inherited class
{
function displayGrandPaName()
{
return $this->name; // The public variable will be available to the inherited class
}
}
// Inherited class Daddy wants to know Grandpas Name
$daddy = new Daddy;
echo $daddy->displayGrandPaName(); // Prints 'Mark Henry'
// Public variables can also be accessed outside of the class!
$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name; // Prints 'Mark Henry'
Lorsque vous déclarez une méthode (fonction) ou une propriété (variable) en tant que protected
, vous pouvez accéder à ces méthodes et propriétés en
Les membres externes ne peuvent pas accéder à ces variables. "Outsiders" en ce sens qu'ils ne sont pas des instances object de la classe déclarée elle-même.
Exemple:
<?php
class GrandPa
{
protected $name = 'Mark Henry';
}
class Daddy extends GrandPa
{
function displayGrandPaName()
{
return $this->name;
}
}
$daddy = new Daddy;
echo $daddy->displayGrandPaName(); // Prints 'Mark Henry'
$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name; // Results in a Fatal Error
L'erreur exacte sera la suivante:
Erreur irrécupérable PHP: impossible d'accéder à la propriété protégée GrandPa :: $ name
Lorsque vous déclarez une méthode (fonction) ou une propriété (variable) en tant que private
, vous pouvez accéder à ces méthodes et propriétés de la manière suivante:
Les membres externes ne peuvent pas accéder à ces variables. Les personnes extérieures au sens où elles ne sont pas des instances object de la classe déclarée elle-même et même des classes qui héritent de la classe déclarée.
Exemple:
<?php
class GrandPa
{
private $name = 'Mark Henry';
}
class Daddy extends GrandPa
{
function displayGrandPaName()
{
return $this->name;
}
}
$daddy = new Daddy;
echo $daddy->displayGrandPaName(); // Results in a Notice
$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name; // Results in a Fatal Error
Les messages d'erreur exacts seront:
Avis: Propriété non définie: Daddy :: $ name
Erreur fatale: impossible d'accéder à la propriété privée GrandPa :: $ name
Ce sujet n’est pas vraiment hors de propos, et je l’ajoute ici juste pour prouver que la réflexion est vraiment puissante. Comme je l'ai indiqué dans les trois exemples ci-dessus, les membres protected
et private
(propriétés et méthodes) ne sont pas accessibles en dehors de la classe.
Cependant, avec réflexion, vous pouvez faire les extraordinaires en accédant même aux membres protected
et private
en dehors de la classe!
Reflection ajoute la possibilité de désosser des classes, des interfaces, fonctions, méthodes et extensions. En outre, ils offrent des moyens de récupère les commentaires de doc pour les fonctions, les classes et les méthodes.
Nous avons une classe nommée Grandpas
et disons que nous avons trois propriétés. Pour faciliter la compréhension, considérez qu'il y a trois grands-pères portant des noms:
Faisons-leur (assigner des modificateurs) public
, protected
et private
respectivement. Vous savez très bien que les membres protected
et private
ne sont pas accessibles en dehors de la classe. Maintenant, contredisons la déclaration en utilisant la réflexion.
<?php
class GrandPas // The Grandfather's class
{
public $name1 = 'Mark Henry'; // This grandpa is mapped to a public modifier
protected $name2 = 'John Clash'; // This grandpa is mapped to a protected modifier
private $name3 = 'Will Jones'; // This grandpa is mapped to a private modifier
}
# Scenario 1: without reflection
$granpaWithoutReflection = new GrandPas;
# Normal looping to print all the members of this class
echo "#Scenario 1: Without reflection<br>";
echo "Printing members the usual way.. (without reflection)<br>";
foreach($granpaWithoutReflection as $k=>$v)
{
echo "The name of grandpa is $v and he resides in the variable $k<br>";
}
echo "<br>";
#Scenario 2: Using reflection
$granpa = new ReflectionClass('GrandPas'); // Pass the Grandpas class as the input for the Reflection class
$granpaNames=$granpa->getDefaultProperties(); // Gets all the properties of the Grandpas class (Even though it is a protected or private)
echo "#Scenario 2: With reflection<br>";
echo "Printing members the 'reflect' way..<br>";
foreach($granpaNames as $k=>$v)
{
echo "The name of grandpa is $v and he resides in the variable $k<br>";
}
Sortie:
#Scenario 1: Without reflection
Printing members the usual way.. (Without reflection)
The name of grandpa is Mark Henry and he resides in the variable name1
#Scenario 2: With reflection
Printing members the 'reflect' way..
The name of grandpa is Mark Henry and he resides in the variable name1
The name of grandpa is John Clash and he resides in the variable name2
The name of grandpa is Will Jones and he resides in the variable name3
S'il vous plaît ne confondez pas avec l'exemple ci-dessous. Comme vous pouvez toujours le constater, les membres private
et protected
ne sont pas accessibles en dehors de de la classe sans utiliser la réflexion.
<?php
class GrandPas // The Grandfather's class
{
public $name1 = 'Mark Henry'; // This grandpa is mapped to a public modifier
protected $name2 = 'John Clash'; // This grandpa is mapped to a protected modifier
private $name3 = 'Will Jones'; // This grandpa is mapped to a private modifier
}
$granpaWithoutReflections = new GrandPas;
print_r($granpaWithoutReflections);
Sortie:
GrandPas Object
(
[name1] => Mark Henry
[name2:protected] => John Clash
[name3:GrandPas:private] => Will Jones
)
print_r
, var_export
et var_dump
sont fonctions de débogage . Ils présentent des informations sur une variable sous une forme lisible par l'homme. Ces trois fonctions révéleront les propriétés protected
et private
des objets avec PHP 5. Les membres statiques de la classe seront non affichés.
Il est généralement considéré comme une bonne pratique de choisir la visibilité la plus faible requise par défaut, car cela favorise l'encapsulation des données et une bonne conception de l'interface. Lorsque vous considérez la visibilité de la variable et de la méthode du membre, réfléchissez au rôle que le membre joue dans l'interaction avec d'autres objets.
Si vous "codez pour une interface plutôt que pour une implémentation", il est généralement assez simple de prendre des décisions de visibilité. En général, les variables doivent être privées ou protégées sauf si vous avez une bonne raison de les exposer. Utilisez plutôt des accesseurs publics (getters/setters) pour limiter et réglementer l'accès aux composants internes d'une classe.
Pour utiliser une voiture comme analogie, des éléments tels que la vitesse, la vitesse et la direction seraient des variables d'instance privées. Vous ne voulez pas que le conducteur manipule directement des choses comme le rapport air/carburant. Au lieu de cela, vous exposez un nombre limité d'actions en tant que méthodes publiques. L'interface vers une voiture peut inclure des méthodes telles que accelerate()
, deccelerate()
/brake()
, setGear()
, turnLeft()
, turnRight()
, etc.
Le conducteur ne sait pas et ne doit pas se soucier de savoir comment ces actions sont mises en œuvre par les internes de la voiture, et exposer cette fonctionnalité pourrait être dangereux pour le conducteur et les autres sur la route. D'où la bonne pratique de concevoir une interface publique et d'encapsuler les données derrière cette interface.
Cette approche vous permet également de modifier et d'améliorer l'implémentation des méthodes publiques dans votre classe sans rompre le contrat de l'interface avec le code client. Par exemple, vous pourriez améliorer la méthode accelerate()
pour qu'elle consomme moins de carburant, mais son utilisation resterait la même; Le code client ne nécessiterait aucun changement, mais tirerait tout de même les avantages de votre amélioration de l'efficacité.
Edit: Puisqu'il semble que vous êtes encore en train d'apprendre des concepts orientés objet (qui sont beaucoup plus difficiles à maîtriser que la syntaxe de n'importe quelle langue), je vivement recommande de prendre un exemplaire de PHP Objets, motifs et pratique par Matt Zandstra. C’est le livre qui m’a appris pour la première fois à comment à utiliser OOP de manière efficace, plutôt que de simplement m'apprendre la syntaxe. J'avais appris la syntaxe des années auparavant, mais c'était inutile sans comprendre le "pourquoi" de la POO.
private - accessible depuis DANS la classe uniquement
protected - peut être accédé depuis les classes WITHIN et INHERITING
public - peut également être consulté à partir du code extérieur de la classe
Ceci s’applique tant aux fonctions qu’aux variables.
La différence est la suivante:
Public
:: Une variable ou une méthode publique est directement accessible à tout utilisateur de la classe.
Protected
:: Une variable ou une méthode protégée n'est pas accessible aux utilisateurs de la classe, mais à l'intérieur d'une sous-classe qui hérite de la classe.
Private
:: Une variable ou méthode privée est accessible uniquement de manière interne depuis la classe dans laquelle elle est définie. Cela signifie qu'une variable ou méthode privée ne peut pas être appelée depuis un enfant qui étend la classe.
Visibilité avec Exemples de résumé :: facilite la compréhension
Cette visibilité d'une propriété ou d'une méthode est définie par la déclaration préalable d'un des trois mots clés (Public, protected et private).
Public : Si une propriété ou une méthode est définie comme publique, cela signifie qu'elle peut être à la fois accessible et manipulée par tout ce qui peut faire référence à object.
Protégé: lorsqu'une propriété ou une méthode a la visibilité sur des membres protégés, l'accès ne peut être accessible qu'à l'intérieur de la classe et par les classes héritées et héritées. (Hérité: - une classe peut avoir toutes les propriétés et les méthodes d'une autre classe).
Private: Quand la visibilité d'une propriété ou d'une méthode est définie sur private, seule la classe possédant les membres privés peut accéder à ces méthodes et propriétés (en interne dans la classe), quelle que soit la relation de classe qui existe.
/**
* Define MyClass
*/
class MyClass
{
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // Works
echo $obj->protected; // Fatal Error
echo $obj->private; // Fatal Error
$obj->printHello(); // Shows Public, Protected and Private
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// We can redeclare the public and protected method, but not private
protected $protected = 'Protected2';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj2 = new MyClass2();
echo $obj2->public; // Works
echo $obj2->private; // Undefined
echo $obj2->protected; // Fatal Error
$obj2->printHello(); // Shows Public, Protected2, Undefined
Voici un moyen facile de mémoriser la portée de
public
,protected
etprivate
.
PUBLIC
:
public
scope: Une variable/fonction publique est disponible pour les objets et les autres classes.PROTECTED
:
protected
scope: Une variable/fonction protégée est disponible pour toutes les classes qui étendent la classe actuelle. PRIVATE
:
private
scope: Une variable/fonction privée n'est visible que dans la classe en cours où elle est définie.Lisez le Visibility d'une méthode ou d'une variable dans le manuel PHP.
Considérant 'when':
Au début, j'ai tendance à tout déclarer privé, si je ne suis pas tout à fait sûr. Raison d'être, il est généralement beaucoup plus facile de rendre publique une méthode privée que l'inverse. C'est parce que vous pouvez au moins être sûr que la méthode privée n'a été utilisée nulle part ailleurs que dans la classe elle-même. Une méthode publique peut déjà être utilisée partout, nécessitant éventuellement une réécriture étendue.
Mise à jour : Je pars pour un défaut de protected
de nos jours, car j’ai découvert que c’est suffisant pour l’encapsulation et qui ne gêne pas lorsque j’étends des classes (que j’essaie d’éviter de toute façon) . Seulement si j'ai une bonne raison d'utiliser les deux autres, je le ferai.
Une bonne méthode pour une méthode private
serait une méthode qui implémenterait quelque chose d'inhérent à cet objet que même une classe étendue ne devrait pas changer (raison factuelle, en plus de l'encapsulation, comme la gestion interne de l'état). En fin de compte, il est toujours assez facile de déterminer où une méthode protected
est habituellement utilisée, aussi, la valeur par défaut est protected
de nos jours. Peut-être pas une expérience 100% objective "dans les tranchées", je l'avoue.
Pour moi, c’est le plus utile moyen de comprendre les trois types de propriétés:
Public : Utilisez ceci quand vous êtes d'accord avec cette variable étant directement accédée et modifiée de n'importe où dans votre code.
Exemple d'utilisation en dehors de la classe:
$myObject = new MyObject()
$myObject->publicVar = 'newvalue';
$pubVar = $myObject->publicVar;
Protected : Utilisez-le lorsque vous voulez obliger les autres programmeurs (et vous-même) à utiliser des accesseurs/séparateurs en dehors de la classe lors de l'accès aux variables et de leur définition (vous devez cependant être cohérent et utiliser les accesseurs et les configurateurs de la classe ). Ce nom ou private
est généralement le moyen par défaut de configurer toutes les propriétés de classe.
Pourquoi? Parce que si vous décidez ultérieurement (peut-être même dans environ 5 minutes) de manipuler la valeur renvoyée pour cette propriété ou de faire quelque chose avec elle avant d'obtenir/de définir, vous pouvez le faire sans refactoring où que vous soyez. utilisé dans votre projet.
Exemple d'utilisation en dehors de la classe:
$myObject = new MyObject()
$myObject->setProtectedVar('newvalue');
$protectedVar = $myObject->getProtectedVar();
Private : Les propriétés private
sont très similaires aux propriétés protected
. Mais la particularité/différence est que rendre private
le rend également inaccessible aux classes enfants sans utiliser le getter ou le setter de la classe parent.
Donc, si vous utilisez des getters et des setters pour une propriété (ou si elle est utilisée uniquement en interne par la classe parente et qu'elle n'est censée être accessible nulle part ailleurs), vous pouvez tout aussi bien en faire private
, simplement pour empêcher quiconque en essayant de l'utiliser directement et introduisant des bugs.
Exemple d'utilisation dans une classe enfant (qui étend MyObject):
$this->setPrivateVar('newvalue');
$privateVar = $this->getPrivateVar();
Le manuel PHP a une bonne lecture sur la question ici .
La visibilité d'une propriété ou d'une méthode peut être définie en préfixant la déclaration avec les mots-clés public, protected ou private. Les membres de classe déclarés publics sont accessibles partout. Les membres déclarés protégés ne sont accessibles qu'au sein de la classe et par les classes héritées et parent. Les membres déclarés comme privés ne peuvent être consultés que par la classe qui définit le membre.
Les variables entre PHP sont exprimées en trois types différents:
Public: les valeurs de cette variable sont disponibles dans toutes les portées et appellent lors de l'exécution de votre code ..__ déclare en tant que: public $examTimeTable;
Private: les valeurs de ce type de variable ne sont disponibles que sur la classe à laquelle il appartient . private $classRoomComputers;
Protected: Valeurs de cette classe uniquement et disponibles uniquement lorsque Access a été accordé sous forme d'héritage ou de sa classe enfant. généralement utilisé ::
pour accorder l'accès par classe parent
protected $familyWealth;
Ils sont là pour permettre différents niveaux de encapsulation
Je reviens à une vieille question, mais je pense que l’API que vous définissez est un très bon moyen d’y réfléchir.
public
- Tout ce qui est marqué comme public fait partie de l'API que toute personne utilisant votre classe/interface/autre utilisera et comptera.
protected
- Ne vous y trompez pas, cela fait également partie de l'API! Les gens peuvent sous-classer, étendre votre code et utiliser tout ce qui est marqué comme protégé.
private
- Les propriétés et méthodes privées peuvent être modifiées autant que vous le souhaitez. Personne d'autre ne peut les utiliser. Ce sont les seules choses que vous pouvez changer sans apporter de modifications radicales.
Ou en Semver termes:
Les modifications apportées à quoi que ce soit public
ou protected
devraient être considérées comme des modifications MAJEURES.
Tout ce qui est nouveau public
ou protected
devrait être (au moins) MINOR
PATCH uniquement les modifications/modifications apportées à une variable private
Donc, en termes de maintenance du code, il est bon de faire attention à ce que vous faites public
ou protected
car ce sont les choses que vous promettez aux utilisateurs.
Lorsque nous suivons php orienté objet dans notre projet, nous devrions suivre certaines règles pour utiliser les modificateurs d'accès en php. Aujourd'hui, nous allons apprendre clairement ce qu'est le modificateur d'accès et comment l'utiliser. Les modificateurs d'accès PHP permettent de définir les droits d'accès avec les classes PHP et leurs membres, qui sont les fonctions et les variables définies dans la portée de la classe. En php, il existe trois champs d'application pour les membres de la classe.
Maintenant, regardons l’image suivante pour comprendre le niveau d’accès au modificateur d’accès
Voyons maintenant la liste suivante pour connaître les mots-clés PHP pouvant être utilisés comme modificateurs d'accès.
public: - la classe ou ses membres définis avec ce modificateur d'accès seront accessibles au public de n'importe où, même de l'extérieur du champ de la classe.
private: - les membres de la classe avec ce mot clé seront accessibles au sein de la classe elle-même. nous ne pouvons pas accéder aux données privées de la sous-classe. Il protège les membres des accès en dehors de la classe.
protected: - idem à private, sauf en autorisant les sous-classes à accéder aux membres protégés de la superclasse.
Maintenant, voyez le tableau pour comprendre le modificateur d'accès. Lire l'article complet php access modifire
Public: est un état par défaut lorsque vous déclarez une variable ou une méthode, accessible directement à l’objet.
Protégé: accessible uniquement dans l'objet et les sous-classes.
Privé: ne peut être référencé que dans l'objet, pas dans les sous-classes.