Kurz gesagt: Objektorientierte Programmierung (OOP) bündelt Daten und die zugehörigen Funktionen in Klassen. PHP bietet dafür Klassen, abstrakte Klassen, Interfaces, Traits und seit PHP 8.1 Enums. Mit PHP 8.0 bis 8.4 kamen viele Sprachmittel hinzu, etwa Konstruktor-Promotion, readonly, Property Hooks und asymmetrische Sichtbarkeit. Für die Sicherheit wichtig: Gut gekapselter Code ist leichter zu prüfen, und magische Methoden machen unsichere Deserialisierung gefährlich. Gegen Lücken im Interpreter wie PHP2Shell hilft OOP nicht.
Was objektorientierte Programmierung in PHP bedeutet
Statt lose Funktionen und globale Variablen zu verwenden, beschreibt eine Klasse ein Ding der Fachwelt: eine Bestellung, einen Kunden, eine Rechnung. Sie legt fest, welche Daten dazugehören (Eigenschaften) und was man damit tun kann (Methoden). Ein Objekt ist ein konkretes Exemplar dieser Klasse.
Für Entscheider hat das einen praktischen Wert: Objektorientierter Code mit klaren Klassen lässt sich besser testen, prüfen und an Dienstleister übergeben. Alte PHP-Anwendungen aus vielen einzelnen Skripten mit globalen Variablen sind dagegen schwer zu warten und bei Upgrades fehleranfällig.
Ein zentraler Gedanke ist die Kapselung: Eine Klasse gibt nach außen nur die Methoden frei, die andere wirklich brauchen, und schützt ihren inneren Zustand. Eine Bestellung lässt sich dann zum Beispiel nur über eine Methode als bezahlt markieren, die vorher prüft, ob das überhaupt zulässig ist. Solche Regeln an einer Stelle zu bündeln, ist auch für die Sicherheit ein Gewinn.
Die Bausteine im Überblick
| Baustein | Zweck | Kurzbeispiel |
|---|---|---|
| Klasse | Bauplan für Objekte mit Eigenschaften und Methoden | class Rechnung { ... } |
| abstrakte Klasse | gemeinsame Basis, nicht direkt instanziierbar | abstract class Zahlart { ... } |
| Interface | Vertrag: welche Methoden eine Klasse anbieten muss | interface Versandfaehig { ... } |
| Trait | wiederverwendbare Methoden für Klassen ohne gemeinsame Elternklasse | trait MitZeitstempel { ... } |
| Enum | fester Satz erlaubter Werte als eigener Typ, seit PHP 8.1 | enum Status { case Offen; ... } |
Sichtbarkeiten (public, protected, private) regeln, wer auf Eigenschaften und Methoden zugreifen darf. Klassen werden in Namespaces organisiert und über einen Autoloader geladen; wie das funktioniert, zeigt die Seite Namespaces und Autoloading.
Modernes PHP: die Neuerungen von 8.0 bis 8.4
Die folgenden Sprachmittel sind im PHP-Handbuch beziehungsweise in den Release-Ankündigungen dokumentiert:
| Version | Neuerung |
|---|---|
| 8.0 | Konstruktor-Promotion, Nullsafe-Operator ?->, ::class auf Objekten |
| 8.1 | readonly-Eigenschaften, Enums, new in Initialisierern, final für Klassenkonstanten |
| 8.2 | readonly-Klassen; dynamische Eigenschaften gelten als veraltet |
| 8.3 | Attribut #[\Override], typisierte Klassenkonstanten |
| 8.4 | Property Hooks, asymmetrische Sichtbarkeit, new ohne umschließende Klammern |
Ein Beispiel, das mehrere dieser Mittel kombiniert:
<?php
declare(strict_types=1);
enum Status: string
{
case Offen = 'offen';
case Bezahlt = 'bezahlt';
}
final class Bestellung
{
public function __construct(
public readonly int $id,
public private(set) Status $status = Status::Offen, // ab PHP 8.4
) {}
public function alsBezahltMarkieren(): void
{
$this->status = Status::Bezahlt;
}
}
$b = new Bestellung(42);
$b->alsBezahltMarkieren();
echo $b->status->value; // bezahlt
$s = Status::tryFrom('storniert'); // null statt Fehler
readonly verhindert, dass die ID nach dem Anlegen geändert wird. private(set) erlaubt das Lesen von außen, das Schreiben aber nur innerhalb der Klasse. Solche Zusicherungen im Code machen Fehler unwahrscheinlicher, die sonst erst im Betrieb auffallen. Die Typen dahinter erklärt die Seite Das Typsystem von PHP.
Upgrade-Fallen im objektorientierten Code
Für ältere Anwendungen sind zwei Änderungen besonders relevant. Seit PHP 8.2.0 ist das Anlegen dynamischer Eigenschaften veraltet, also von Eigenschaften, die in der Klasse nicht deklariert sind, es sei denn, die Klasse trägt das Attribut #[\AllowDynamicProperties]. Älterer Code nutzt das oft unbewusst und füllt die Logs dann mit Hinweisen. Außerdem müssen typisierte Eigenschaften laut Handbuch vor dem ersten Lesen initialisiert sein, sonst wirft PHP einen Error.
Hilfreich ist das Attribut #[\Override] aus PHP 8.3: Es markiert eine Methode als Überschreibung einer Elternmethode. Gibt es diese Methode nicht mehr, etwa nach einer Umbenennung in einer Bibliothek, meldet PHP einen Fehler, statt die Methode still ins Leere laufen zu lassen. Solche Prüfungen machen Upgrades planbarer; bei festgefahrenen Altprojekten hilft unsere Migration auf eine unterstützte PHP-Version.
Objekte und Speicher
Objekte werden in PHP über Kennungen (Handles) weitergegeben. Übergibt man ein Objekt an eine Funktion, arbeitet diese mit demselben Objekt, nicht mit einer Kopie. Das ist effizient, führt aber leicht zu Kreisbezügen, etwa wenn eine Bestellung ihre Positionen kennt und jede Position wieder ihre Bestellung. Solche Zyklen räumt die Referenzzählung allein nicht auf; dafür hat PHP einen eigenen Garbage Collector. Details stehen auf der Seite Speicherverwaltung in PHP.
OOP und Sicherheit: magische Methoden und Deserialisierung
PHP kennt magische Methoden, die automatisch aufgerufen werden, etwa __construct, __destruct, __toString, __get oder __wakeup. Das ist praktisch, hat aber eine Schattenseite: Wenn eine Anwendung fremde Daten mit unserialize() in Objekte zurückverwandelt, kann ein Angreifer bestimmen, welche Klassen entstehen, und damit vorhandenen Code in magischen Methoden anstoßen. Wie man das verhindert, beschreibt der Ratgeber Unsichere Deserialisierung in PHP. Kurz: Für den Datenaustausch json_encode() und json_decode() verwenden und unserialize() nur für eigene, vertrauenswürdige Daten nutzen, idealerweise mit der Option allowed_classes.
Bei PHP2Shell hilft guter objektorientierter Code dagegen nicht. CVE-2026-109618 und CVE-2026-109619 liegen im Interpreter, und bei mod_php wurde laut PHP-Team ein Exploit gezeigt, bevor Anwendungscode läuft. Pflicht ist das Update auf PHP 8.5.12, 8.4.27, 8.3.36 oder 8.2.35 und der Neustart aller PHP-Prozesse.
Wie hilft PHP SOS konkret?
- Wir bewerten den Aufbau Ihrer Anwendung und zeigen, welche Teile ein Upgrade auf eine unterstützte PHP-Version erschweren.
- Wir suchen gezielt nach riskanten Mustern wie
unserialize()auf fremden Daten und gefährlichen magischen Methoden. - Wir prüfen Eigenentwicklungen im Rahmen eines Sicherheitsaudits und Penetrationstests.
- Wir spielen das PHP-Update ein, starten alle Worker neu und testen die Anwendung danach.
Häufige Fragen
Ist PHP eine objektorientierte Sprache?
PHP unterstützt sowohl prozeduralen als auch objektorientierten Code. Frameworks, CMS-Kerne und Shopsysteme sind heute aber überwiegend objektorientiert aufgebaut, mit Klassen, Interfaces und Namespaces.
Was ist der Unterschied zwischen Interface und abstrakter Klasse?
Ein Interface beschreibt nur, welche Methoden eine Klasse anbieten muss. Eine abstrakte Klasse kann zusätzlich schon Code und Eigenschaften enthalten, lässt sich aber nicht direkt instanziieren. Eine Klasse kann mehrere Interfaces, aber nur eine Elternklasse haben.
Seit wann gibt es Enums in PHP?
Enumerationen kamen mit PHP 8.1. Sie ersetzen Sammlungen von Konstanten durch einen eigenen Typ, der nur die definierten Fälle zulässt. Backed Enums haben zusätzlich einen int- oder string-Wert.
Warum sind magische Methoden sicherheitsrelevant?
Methoden wie __destruct oder __wakeup ruft PHP automatisch auf, zum Beispiel beim Entserialisieren von Daten. Gelangen fremde Daten ungeprüft in unserialize(), kann das unerwartete Abläufe in vorhandenen Klassen auslösen.