11 Objektorientierte Programmierung in PHP

11.1 Klassen und Objekte

Die objektorientierte Programmierung (OOP) in PHP ermöglicht es, Code modular, wiederverwendbar und besser wartbar zu gestalten. Seit PHP 5 und besonders in aktuellen Versionen wurden die OOP-Funktionen erheblich erweitert und verbessert. In diesem Abschnitt erlernen Sie die Grundlagen der Klassendefinition und Objekterstellung in PHP.

11.1.1 Grundkonzepte der OOP

Die objektorientierte Programmierung basiert auf vier Hauptprinzipien:

  1. Kapselung - Das Verbergen interner Zustände und Funktionalitäten
  2. Abstraktion - Die Vereinfachung komplexer Systeme durch Modellierung
  3. Vererbung - Die Möglichkeit, Eigenschaften und Methoden von Elternklassen zu übernehmen
  4. Polymorphismus - Die Fähigkeit, verschiedene Formen anzunehmen

In PHP werden diese Konzepte durch Klassen und Objekte implementiert.

11.1.2 Definition einer Klasse

Eine Klasse ist eine Vorlage oder ein Bauplan, der die Eigenschaften (Attribute) und Verhaltensweisen (Methoden) definiert. In PHP wird eine Klasse mit dem Schlüsselwort class definiert:

class Buch {
    // Eigenschaften (Properties)
    public $titel;
    public $autor;
    public $seitenzahl;
    
    // Methoden
    public function vollständigerTitel() {
        return $this->titel . " von " . $this->autor;
    }
}

11.1.3 Eigenschaften (Properties)

Eigenschaften sind Variablen, die zu einer Klasse gehören. Sie repräsentieren den Zustand eines Objekts. In PHP können Eigenschaften einen Zugriffsmodifikator haben:

Seit PHP 7.4 können Eigenschaften auch typisiert werden:

class Buch {
    public string $titel;
    public string $autor;
    public int $seitenzahl;
}

11.1.4 Methoden

Methoden sind Funktionen, die zu einer Klasse gehören. Sie definieren das Verhalten von Objekten:

class Buch {
    public string $titel;
    public string $autor;
    
    public function setTitel(string $titel): void {
        $this->titel = $titel;
    }
    
    public function getTitel(): string {
        return $this->titel;
    }
}

11.1.5 Der Konstruktor

Der Konstruktor ist eine spezielle Methode, die bei der Erstellung eines Objekts automatisch aufgerufen wird. In PHP wird der Konstruktor mit __construct() definiert:

class Buch {
    public string $titel;
    public string $autor;
    public int $seitenzahl;
    
    public function __construct(string $titel, string $autor, int $seitenzahl = 0) {
        $this->titel = $titel;
        $this->autor = $autor;
        $this->seitenzahl = $seitenzahl;
    }
}

11.1.6 Objekterzeugung und -verwendung

Nach der Definition einer Klasse können Objekte (Instanzen) erstellt werden:

// Objekt erstellen
$meinBuch = new Buch("PHP: Moderne Entwicklung für Profis", "Max Mustermann", 350);

// Auf Eigenschaften zugreifen
echo $meinBuch->titel; // Ausgabe: PHP: Moderne Entwicklung für Profis

// Methoden aufrufen
echo $meinBuch->vollständigerTitel(); 
// Ausgabe: PHP: Moderne Entwicklung für Profis von Max Mustermann

11.1.7 Der $this-Verweis

Innerhalb von Methoden bezieht sich $this auf das aktuelle Objekt und wird verwendet, um auf Eigenschaften und andere Methoden des Objekts zuzugreifen.

class Benutzer {
    public string $vorname;
    public string $nachname;
    
    public function vollständigerName(): string {
        return $this->vorname . " " . $this->nachname;
    }
    
    public function begrüßung(): string {
        return "Hallo " . $this->vollständigerName() . "!";
    }
}

11.1.8 Statische Eigenschaften und Methoden

Statische Eigenschaften und Methoden gehören zur Klasse selbst und nicht zu einer bestimmten Instanz. Sie werden mit dem Schlüsselwort static definiert und mit dem Scope-Resolution-Operator :: aufgerufen:

class Mathematik {
    public static float $pi = 3.14159;
    
    public static function quadrat(float $zahl): float {
        return $zahl * $zahl;
    }
}

// Verwendung ohne Objektinstanziierung
echo Mathematik::$pi; // Ausgabe: 3.14159
echo Mathematik::quadrat(4); // Ausgabe: 16

11.1.9 Konstanten in Klassen

Klassenkonstanten bieten einen Weg, unveränderliche Werte pro Klasse zu definieren:

class Datenbankverbindung {
    const HOST = "localhost";
    const USER = "admin";
    const DATABASE = "meine_datenbank";
    
    public function verbinden(): void {
        echo "Verbindung zu " . self::HOST . " herstellen...";
    }
}

// Zugriff auf Konstanten
echo Datenbankverbindung::HOST; // Ausgabe: localhost

In der Methode verbinden() wird mit self::HOST auf die Konstante zugegriffen. self bezieht sich dabei auf die aktuelle Klasse.

11.1.10 Sichtbarkeit und Zugriffsmodifikatoren

PHP bietet drei Zugriffsmodifikatoren, um die Sichtbarkeit von Eigenschaften und Methoden zu kontrollieren:

class Produkt {
    private float $preis; // Nur innerhalb dieser Klasse zugänglich
    protected string $name; // Zugänglich in dieser Klasse und abgeleiteten Klassen
    public string $beschreibung; // Überall zugänglich
    
    public function setPreis(float $preis): void {
        if ($preis > 0) {
            $this->preis = $preis;
        }
    }
    
    public function getPreis(): float {
        return $this->preis;
    }
}

Diese Kapselung ist ein wichtiger Aspekt der OOP, da sie die Datenintegrität sicherstellt und die interne Implementierung verbirgt.

11.1.11 Getter und Setter

Getter und Setter sind Methoden, die den kontrollierten Zugriff auf private oder protected Eigenschaften ermöglichen:

class Benutzer {
    private string $passwort;
    
    public function setPasswort(string $passwort): void {
        // Validierung und Hashing vor dem Speichern
        if (strlen($passwort) >= 8) {
            $this->passwort = password_hash($passwort, PASSWORD_DEFAULT);
        } else {
            throw new Exception("Passwort muss mindestens 8 Zeichen lang sein");
        }
    }
    
    public function istPasswortKorrekt(string $passwort): bool {
        return password_verify($passwort, $this->passwort);
    }
}

11.1.12 Klassen-Autoloading

In größeren Projekten ist es üblich, jede Klasse in einer separaten Datei zu definieren. PHP bietet Autoloading-Funktionen, um Klassen automatisch zu laden, wenn sie benötigt werden:

spl_autoload_register(function($klassenName) {
    include 'klassen/' . $klassenName . '.php';
});

// Die Klasse wird automatisch geladen
$benutzer = new Benutzer();

In modernen PHP-Projekten wird dieses Feature jedoch meist durch Composer’s Autoloading-Mechanismus ersetzt, wie später im Kapitel über Paketverwaltung besprochen wird.

11.1.13 Praktisches Beispiel: Ein einfaches Blog-System

Betrachten wir ein praktisches Beispiel, das die bisher besprochenen Konzepte zusammenfasst:

class BlogPost {
    private int $id;
    private string $titel;
    private string $inhalt;
    private string $autor;
    private DateTime $erstelltAm;
    
    public function __construct(string $titel, string $inhalt, string $autor) {
        $this->titel = $titel;
        $this->inhalt = $inhalt;
        $this->autor = $autor;
        $this->erstelltAm = new DateTime();
    }
    
    public function getTitel(): string {
        return $this->titel;
    }
    
    public function getKurzfassung(int $länge = 100): string {
        return substr($this->inhalt, 0, $länge) . '...';
    }
    
    public function anzeigen(): string {
        return "<article>
                    <h2>{$this->titel}</h2>
                    <p>Verfasst von {$this->autor} am {$this->erstelltAm->format('d.m.Y')}</p>
                    <div>{$this->inhalt}</div>
                </article>";
    }
}

// Verwendung
$post = new BlogPost(
    "Einführung in die OOP mit PHP",
    "Objektorientierte Programmierung ist ein wichtiges Konzept in PHP...",
    "Max Mustermann"
);

echo $post->anzeigen();

11.1.14 Zusammenfassung

Klassen und Objekte bilden die Grundlage der objektorientierten Programmierung in PHP. Durch die Kapselung von Daten und Funktionalität in Klassen wird der Code modularer, wiederverwendbarer und besser strukturiert. In den folgenden Abschnitten werden wir auf diesen Grundlagen aufbauen und fortgeschrittenere OOP-Konzepte wie Vererbung, Interfaces und Traits untersuchen.