Les modificateurs d'accès fournissent le mode d'accessibilité (ou de visibilité) des membres d'une classe.

Il existe trois types d'accessibilité en PHP.

  • public : les membres publiques sont visibles sans restriction dans tout le programme,
  • protected : les membres protégés ne peuvent être accédés que par la classe qui les a déclarés et par les classes qui héritent de cette dernière,
  • private : les membres privés ne sont visibles que dans la classe qui les a déclarés.

Les attributs d'une classe ne peuvent être accédés dans la hiérarchie de classes et en dehors de celles-ci, qu'en utilisant respectivement la référence à l'objet en cours $this et qu'à partir d'une instance de classe.

class Classe {
  public $attribut;
  public function Classe($valeur){
    //$attribut = $valeur; //ERREUR !!!
    $this->attribut = $valeur;
  }
}
//echo $attribut; //ERREUR !!!
//echo Classe->$attribut; //ERREUR !!!
$o = new Classe(10); //Instanciation d'une classe
echo $o->$attribut();

Une classe peut être complétement encapsulée en déclarant privé tous ses attributs, mais en permetant à des méthodes dites accesseurs et mutateurs de respectivement accéder et modifier les attributs privés, créant ainsi une interface publique pour leur accés et leur modification.

class Classe {
  private $attribut;
  public function Classe(){
    $this->attribut = null;
  }
  //Accesseur
  public function getAttribut(){
    return $this->attribut;
  }
  //Mutateur
  public function setAttribut($valeur){
    $this->attribut = $valeur;
  }
}
$o = new Classe(); //Instanciation d'une classe
$o->setAttribut(10);
echo $o->getAttribut();

Dans la mesure du possible, tous les attributs d'une classe doivent être privés afin de respecter les principes de l'encapsulation.

Les membres statiques obéissent aux même règles d'accessibilité que les membres d'instance, à l'exception de l'accès par un objet, qui dans leur cas, utilisent le nom de la classe où ils ont été déclarés. Au sein de leur classe, les membres statiques emploient l'opérateur de résolution de portée :: avec le mot-clé self, au sein d'une classe étendue, il suffit de modifier le mot-clé par parent.

class Classe {
  public static $membre_statique = 16;
  public static function autreMembre(){
    return sqrt(self::$membre_statique);
  }
}
class SousClasse extends Classe{
  private static $membre_statique_2 = 2;
  public static function unAutreMembre(){
    return pow(parent::$membre_statique, 
               self::$membre_statique_2);
  }
}

$o = new Classe();
//echo $o->membre_statique; //ERREUR!!!
//echo $o->autreMembre(); //ERREUR!!!
echo Classe::$membre_statique;
echo Classe::autreMembre();

//echo SousClasse->$membre_statique_2; //ERREUR!!!
echo SousClasse::unAutreMembre();

Les constantes nécessitent une méthode d'accès identiques à ceux des membres de classe, hormis qu'ils n'ont pas besoin de modificateurs d'accès et disposent d'une accessibilité publique.

class SuperClasse {
  private $prive;
  protected $protege;
  public $public;
  //$sans = 'Sans modificateur'; //ERREUR !!!

  public function __construct(){
    $this->prive = 'Attribut privé !';
    $this->protege = 'Attribut protégé !';
    $this->public = 'Attribut public !';
  }

  public function __toString(){
    return '<p>[' . $this->prive . ', '
               . $this->protege . ', '
               . $this->public . ']</p>';
  }

  protected function representer($separateur, $finligne){
    return $this->concatener($separateur) . $finligne;
  }

  private function concatener($separateur){
    return $this->prive . $separateur
        .  $this->protege . $separateur
        .  $this->public;
  }

  //Mutateur
  public function setPrive($valeur){
    $this->prive = $valeur;
  }

  //Accesseur
  public function getPrive(){
    return $this->prive;
  }
}

class ClasseDerivee extends SuperClasse {
  const CRLF = '<br/>';
  private $separateur;

  public function __construct($separateur){
    //$this->prive = 'Attribut privé !'; //ERREUR !!!
    $this->protege = 'Attribut protégé défini dans la classe dérivée !';
    $this->public = 'Attribut public défini dans la classe dérivée !';
    $this->separateur = $separateur;
  }

  public function __toString(){
    return parent::__toString();
  }

  public function apercu(){
    return $this->representer($this->separateur, self::CRLF);
    //SuperClasse->concatener(string sep) est inaccessible !
    //return $this->concatener($this->separateur) . self::CRLF;
  }
}

class UneAutreClasse {
  public function afficher(){
    $sc = new SuperClasse(); //Appel implicite à SuperClasse->__construct()
    echo $sc->publique . ClasseDerivee::CRLF;
  }
}

$superclasse = new SuperClasse(); //Appel implicite à __construct()
echo $superclasse->public;
echo ClasseDerivee::CRLF;
//echo $superclasse->protege; //ERREUR !!!
//echo $superclasse->prive; //ERREUR !!!

echo $superclasse; //Appel implicite à __toString()

$superclasse->setPrive('Attribut privé modifié en dehors de la classe !');
echo $superclasse->getPrive();
echo ClasseDerivee::CRLF;

echo $superclasse; //Appel implicite à __toString()
//echo $superclasse->representer(';', '\n'); //ERREUR !!!
//echo $superclasse->concatener('\t') . '\n'; //ERREUR !!!

$classederivee = new ClasseDerivee(); //Appel implicite à __construct()
//echo $classederivee->separateur; //ERREUR !!!
echo $classederivee; //Appel implicite à __toString()
echo $classederivee->apercu();

$uneautreclasse = new UneAutreClasse();
$uneautreclasse->afficher();