W3docs

Modificatori di Accesso PHP OOP: Guida Completa

I modificatori di accesso in PHP OOP (public, protected, private) controllano la visibilità di proprietà, metodi e costanti per un codice sicuro e robusto.

I modificatori di accesso (detti anche parole chiave di visibilità) determinano chi può leggere, modificare o chiamare un membro di una classe. Sono il meccanismo alla base dell'incapsulamento — uno dei concetti fondamentali della Programmazione Orientata agli Oggetti: si espone una superficie pubblica ridotta e sicura, nascondendo i dettagli interni che i chiamanti non dovrebbero toccare.

Questo capitolo tratta le tre parole chiave di visibilità PHP — public, protected e private — cosa consente ciascuna, cosa succede quando si violano le regole, come si comporta la visibilità nell'ereditarietà, e i pattern comuni (getter, setter e promozione del costruttore) che vi si basano. Se le classi sono nuove per te, leggi prima Classi e Oggetti PHP.

I tre modificatori di accesso in sintesi

ModificatoreAll'interno della stessa classeIn una classe figliaDall'esterno (es. $obj->member)
public
protected
private

Puoi applicare un modificatore a proprietà, metodi e costanti di classe. Se ometti il modificatore su un metodo, PHP lo imposta di default a public; su una proprietà devi indicarlo esplicitamente (la vecchia parola chiave var è un alias di public).

Modificatore di accesso public

public è il livello più permissivo. Un membro pubblico può essere acceduto da qualsiasi luogo — all'interno della classe, dalle classi figlie e da qualsiasi codice che detiene l'oggetto. Usalo per l'interfaccia intesa della tua classe: i metodi che i chiamanti sono destinati a usare.

<?php
class User {
  public $name;

  public function setName($name) {
    $this->name = $name;
  }

  public function getName() {
    return $this->name;
  }
}

$user = new User();
$user->setName("Ada");      // calling a public method
echo $user->getName();      // Ada
echo "\n";
$user->name = "Grace";      // touching a public property directly
echo $user->name;           // Grace

L'output è:

Ada
Grace

Poiché $name è public, i chiamanti possono modificarlo direttamente con $user->name = ..., aggirando setName(). Questo è esattamente il motivo per cui le proprietà public sono spesso sconsigliate: si perde la possibilità di validare il valore. Contrassegnare la proprietà come protected o private ed esporla tramite metodi ripristina quel controllo.

Modificatore di accesso protected

protected si colloca nel mezzo. Il membro è raggiungibile dall'interno della classe e da qualsiasi sottoclasse, ma non dal codice esterno. Usalo quando una sottoclasse ha legittimamente bisogno dei dati, ma i chiamanti esterni non dovrebbero averli.

<?php
class User {
  protected $email;

  protected function setEmail($email) {
    $this->email = $email;
  }

  public function getEmail() {
    return $this->email;
  }
}

$user = new User();
echo $user->getEmail();   // works: getEmail() is public
$user->setEmail("[email protected]"); // Fatal error: Call to protected method User::setEmail()

L'esecuzione di questo codice non stampa nulla per la prima riga (l'email è ancora null) e poi si interrompe con:

PHP Fatal error:  Uncaught Error: Call to protected method User::setEmail() from global scope

L'errore è il punto centrale: i membri protected proteggono la classe dall'uso improprio da parte del codice esterno, cooperando comunque con la catena di ereditarietà mostrata di seguito.

Modificatore di accesso private

private è il livello più restrittivo. Il membro è visibile solo all'interno della classe che lo dichiara — nemmeno le sottoclassi possono vederlo. Usa private quando un dettaglio è puramente interno e potrebbe cambiare in qualsiasi momento, come un hash di password o un calcolo in cache.

<?php
class User {
  private $password;

  public function setPassword($password) {
    // hide the real value behind validation
    $this->password = password_hash($password, PASSWORD_DEFAULT);
  }

  public function check($attempt) {
    return password_verify($attempt, $this->password);
  }
}

$user = new User();
$user->setPassword("s3cret");
var_dump($user->check("s3cret"));  // bool(true)
var_dump($user->check("wrong"));   // bool(false)

L'output è:

bool(true)
bool(false)

Tentare di leggere $user->password dall'esterno della classe genera Error: Cannot access private property User::$password. Il chiamante può interagire solo tramite i metodi public setPassword() e check() — l'hash grezzo è sigillato.

Modificatori di accesso ed ereditarietà

Quando una classe figlia estende una classe genitore, eredita i membri del genitore insieme alla loro visibilità. I membri public e protected sono utilizzabili all'interno della classe figlia; quelli private non sono visibili alla classe figlia.

<?php
class User {
  protected $email;

  protected function setEmail($email) {
    $this->email = $email;
  }

  public function getEmail() {
    return $this->email;
  }
}

class Admin extends User {
  // Admin can call the protected setEmail() because it is a subclass
  public function updateEmail($email) {
    $this->setEmail($email);
  }
}

$admin = new Admin();
$admin->updateEmail("[email protected]");
echo $admin->getEmail();   // [email protected]

L'output è:

Una classe figlia può anche ampliare la visibilità (protectedpublic) quando sovrascrive un membro, ma non può restringerla — sovrascrivere un metodo public come private genera un errore fatale. Per ulteriori informazioni sulla costruzione di gerarchie di classi, vedi Ereditarietà PHP.

Visibilità su costanti e promozione del costruttore

Le costanti di classe accettano gli stessi modificatori (da PHP 7.1). Questo consente di esporre alcune costanti nascondendo i valori di configurazione interni:

<?php
class Order {
  public const STATUS_PAID = "paid";
  private const TAX_RATE = 0.2;   // internal detail

  public function total(float $net): float {
    return $net * (1 + self::TAX_RATE);
  }
}

echo Order::STATUS_PAID;            // paid
echo "\n";
echo (new Order())->total(100);    // 120

L'output è:

paid
120

Da PHP 8.0, la promozione delle proprietà del costruttore consente di dichiarare una proprietà e la sua visibilità direttamente nella firma del costruttore, eliminando il codice boilerplate ripetitivo:

<?php
class Point {
  public function __construct(
    public int $x = 0,
    private int $y = 0,   // declared, assigned, and made private in one line
  ) {}

  public function describe(): string {
    return "x={$this->x}, y={$this->y}";
  }
}

echo (new Point(3, 4))->describe();  // x=3, y=4

L'output è:

x=3, y=4

Vedi Costanti di Classe PHP e Costruttore PHP per il quadro completo di queste funzionalità.

Scegliere il modificatore giusto

  • Inizia con il livello più restrittivo (private) e allentalo solo quando si presenta un'esigenza reale. Questo mantiene piccola la tua API pubblica e facile da modificare in seguito.
  • Rendi un membro public quando fa parte dell'interfaccia da cui dipendono i chiamanti.
  • Rendilo protected quando le sottoclassi — ma non il codice esterno — ne hanno bisogno.
  • Rendilo private quando è un dettaglio implementativo che potrebbe cambiare senza preavviso.
  • Preferisci le proprietà private/protected con metodi getter/setter pubblici rispetto alle proprietà public, così mantieni il controllo su come i valori vengono letti e scritti. Questa idea fa parte di cosa riguarda la OOP.

I modificatori di accesso controllano la visibilità dei membri di classe: public consente l'accesso da qualsiasi luogo, protected dalla classe e dalle sue sottoclassi, e private solo dalla classe che li dichiara. Si applicano a proprietà, metodi e costanti, e sono il modo in cui PHP impone l'incapsulamento. Usati correttamente — nascondendo i dettagli dietro una piccola superficie pubblica — rendono il codice più sicuro da modificare e più facile da comprendere.

Pratica

Pratica
Cosa sono i Modificatori di Accesso in PHP e cosa fanno?
Cosa sono i Modificatori di Accesso in PHP e cosa fanno?
Was this page helpful?