W3docs

PHP OOP Zugriffsmodifikatoren: Ein umfassender Leitfaden

Zugriffsmodifikatoren in PHP OOP steuern die Sichtbarkeit von Klassenmitgliedern. Lernen Sie public, protected und private mit praktischen Beispielen kennen.

Zugriffsmodifikatoren (auch Sichtbarkeits-Schlüsselwörter genannt) legen fest, wer ein Klassenmitglied lesen, ändern oder aufrufen darf. Sie sind der Mechanismus hinter der Kapselung — einem der Kernkonzepte der objektorientierten Programmierung: Man legt eine kleine, sichere öffentliche Oberfläche frei und verbirgt die internen Details, die Aufrufer nicht berühren sollen.

Dieses Kapitel behandelt die drei PHP-Sichtbarkeits-Schlüsselwörter — public, protected und private —, was jedes davon erlaubt, was passiert, wenn man gegen die Regeln verstößt, wie sich Sichtbarkeit bei Vererbung verhält, und die gängigen Muster (Getter, Setter und Constructor Promotion), die darauf aufbauen. Falls Klassen neu für Sie sind, lesen Sie zuerst PHP Classes and Objects.

Die drei Zugriffsmodifikatoren auf einen Blick

ModifikatorInnerhalb derselben KlasseIn einer KindklasseVon außen (z. B. $obj->member)
public
protected
private

Ein Modifikator kann auf Eigenschaften, Methoden und Klassenkonstanten angewendet werden. Wird der Modifikator bei einer Methode weggelassen, setzt PHP standardmäßig public; bei einer Eigenschaft muss er explizit angegeben werden (das alte Schlüsselwort var ist ein Alias für public).

Public-Zugriffsmodifikator

public ist die offenste Stufe. Ein öffentliches Mitglied kann von überall zugegriffen werden — innerhalb der Klasse, aus Kindklassen und aus beliebigem Code, der das Objekt hält. Verwenden Sie es für die vorgesehene Schnittstelle Ihrer Klasse: die Methoden, die Aufrufer nutzen sollen.

<?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

Die Ausgabe ist:

Ada
Grace

Da $name öffentlich ist, können Aufrufer es direkt mit $user->name = ... ändern und dabei setName() umgehen. Genau deshalb werden öffentliche Eigenschaften oft nicht empfohlen: Man verliert die Möglichkeit, den Wert zu validieren. Die Eigenschaft als protected oder private zu markieren und über Methoden freizugeben stellt diese Kontrolle wieder her.

Protected-Zugriffsmodifikator

protected liegt in der Mitte. Das Mitglied ist von innerhalb der Klasse und aus jeder Unterklasse erreichbar, aber nicht von externem Code. Verwenden Sie es, wenn eine Unterklasse die Daten legitimerweise benötigt, externe Aufrufer aber nicht.

<?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()

Die Ausführung gibt für die erste Zeile nichts aus (die E-Mail ist noch null) und bricht dann mit folgender Meldung ab:

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

Der Fehler macht das Prinzip deutlich: Protected-Mitglieder schützen die Klasse vor Missbrauch durch externen Code, während sie weiterhin mit der unten gezeigten Vererbungskette zusammenarbeiten.

Private-Zugriffsmodifikator

private ist die restriktivste Stufe. Das Mitglied ist nur innerhalb der deklarierenden Klasse sichtbar — nicht einmal Unterklassen können darauf zugreifen. Verwenden Sie private, wenn ein Detail rein intern ist und sich jederzeit ändern könnte, wie ein Passwort-Hash oder eine gecachte Berechnung.

<?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)

Die Ausgabe ist:

bool(true)
bool(false)

Der Versuch, $user->password von außerhalb der Klasse zu lesen, löst Error: Cannot access private property User::$password aus. Der Aufrufer kann nur über die öffentlichen Methoden setPassword() und check() interagieren — der rohe Hash ist versiegelt.

Zugriffsmodifikatoren und Vererbung

Wenn eine Kindklasse eine Elternklasse erweitert, erbt sie die Mitglieder der Elternklasse zusammen mit ihrer Sichtbarkeit. public- und protected-Mitglieder sind in der Kindklasse verwendbar; private-Mitglieder sind für die Kindklasse überhaupt nicht sichtbar.

<?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]

Die Ausgabe ist:

Eine Kindklasse kann die Sichtbarkeit beim Überschreiben auch erweitern (protectedpublic), aber nicht einschränken — das Überschreiben einer öffentlichen Methode als private löst einen schwerwiegenden Fehler aus. Mehr zum Aufbau von Klassenhierarchien finden Sie unter PHP Inheritance.

Sichtbarkeit bei Konstanten und Constructor Promotion

Klassenkonstanten akzeptieren dieselben Modifikatoren (seit PHP 7.1). So können Sie einige Konstanten freigeben und interne Einstellungswerte verbergen:

<?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

Die Ausgabe ist:

paid
120

Seit PHP 8.0 ermöglicht die Constructor Property Promotion, eine Eigenschaft und ihre Sichtbarkeit direkt in der Konstruktorsignatur zu deklarieren, was wiederholenden Boilerplate-Code vermeidet:

<?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

Die Ausgabe ist:

x=3, y=4

Siehe PHP Class Constants und PHP Constructor für das vollständige Bild dieser Funktionen.

Den richtigen Modifikator wählen

  • Beginnen Sie mit der restriktivsten Stufe (private) und lockern Sie nur dann, wenn ein echter Bedarf entsteht. So bleibt Ihre öffentliche API klein und leicht veränderbar.
  • Machen Sie ein Mitglied public, wenn es Teil der Schnittstelle ist, auf die Aufrufer angewiesen sind.
  • Machen Sie es protected, wenn Unterklassen — aber kein externer Code — es benötigen.
  • Machen Sie es private, wenn es ein Implementierungsdetail ist, das sich ohne Vorankündigung ändern könnte.
  • Bevorzugen Sie private/protected Eigenschaften mit öffentlichen Getter-/Setter-Methoden gegenüber öffentlichen Eigenschaften, damit Sie die Kontrolle darüber behalten, wie Werte gelesen und geschrieben werden. Diese Idee gehört zu dem, worum es bei OOP geht.

Zusammenfassung

Zugriffsmodifikatoren steuern die Sichtbarkeit von Klassenmitgliedern: public erlaubt Zugriff von überall, protected von der Klasse und ihren Unterklassen, und private nur von der deklarierenden Klasse. Sie gelten für Eigenschaften, Methoden und Konstanten und sind der Mechanismus, mit dem PHP Kapselung durchsetzt. Gut eingesetzt — Details hinter einer kleinen öffentlichen Oberfläche verbergend — machen sie Ihren Code sicherer zu ändern und leichter nachzuvollziehen.

Übungen

Übung
Was sind die Zugriffsmodifikatoren in PHP und was bewirken sie?
Was sind die Zugriffsmodifikatoren in PHP und was bewirken sie?
Was this page helpful?