Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Script Mods
 phpBB Adsense Mode

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 TLD Liste
 Webkatalog‑Verzeichnis

Partner
 Sprüche Treff

Artfiles.de
Bietet Serviceorientierte...
https://www.Artfiles.de
Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains...
https://www.Hosterplus.de
 
 
 

PHP switch: Umfassende Anleitung für Kontrollstrukturen (mit PHP 8.4 / match-Vergleich)

Sie befinden sich: Home > Php Tutorial > PHP switch und match:...

PHP switch und match: Kontrollstrukturen richtig einsetzen


Eintrag am:  12.05.2025
Hits / Besucher:  687
Sprache:  Deutsch
Kategorie:  Einsteiger Tutorials
Tutorial Art:  eigenes
Eingetragen von   schubertmedia schubertmedia
 
Beschreibung

Kontrollstrukturen bestimmen, welcher Codeblock in einem Programm ausgeführt wird. In PHP stehen dafür neben if und elseif auch switch und seit PHP 8.0 der match-Ausdruck zur Verfügung. Während switch seit den Anfängen von PHP existiert, bringt match strikte Typvergleiche und einen Rückgabewert mit. Dieses Tutorial erklärt beide Kontrollstrukturen im Detail, zeigt die Unterschiede und hilft bei der Entscheidung, wann welche die bessere Wahl ist.

Titelbild eines PHP-Tutorials mit Flussdiagramm zu if, elseif, else und hervorgehobener switch-Struktur mit dem Text „PHP switch erklärt (mit match)“.

Die Grundlagen der PHP switch-Anweisung

Die switch-Anweisung vergleicht einen Ausdruck mit mehreren möglichen Werten. Im Gegensatz zu einer langen if-elseif-Kette ist switch übersichtlicher, wenn derselbe Ausdruck gegen viele Werte geprüft werden soll.

Syntax und Kernkomponenten

Jeder case-Block endet mit break, um die weitere Ausführung zu stoppen. Ohne break läuft der Code in den nächsten Case hinein (sogenanntes Fallthrough). Der default-Block greift, wenn kein case zutrifft.

Flussdiagramm mit Entscheidung, Trefferprüfung, break-Anweisung und Ende zur Visualisierung eines switch-Ablaufs.

<?php

switch ($ausdruck) {
case 'Wert1':
// Code für Wert1
break;
case 'Wert2':
case 'Wert3':
/* Code für Wert2
und Wert3 (Fallthrough) */
break;
default:
// Standardaktion
break;
}
?>
BestandteilBeschreibung
switch ($expr)Der Ausdruck, der ausgewertet wird
case 'Wert':Vergleichswert (loses ==)
break;Beendet den aktuellen Case-Block
default:Wird ausgeführt, wenn kein Case passt

Einfache Beispiele

Ein typisches Einstiegsbeispiel ist die Zuordnung von Wochentagen. Hier zeigt sich der Vorteil gegenüber einer langen if-elseif-Kette besonders deutlich:

<?php

$tag = date('N'); // 1=Mo, 7=So

switch ($tag) {
case 1:
echo 'Montag';
break;
case 2:
echo 'Dienstag';
break;
case 3:
echo 'Mittwoch';
break;
case 4:
echo 'Donnerstag';
break;
case 5:
echo 'Freitag';
break;
case 6:
case 7:
echo 'Wochenende!';
break;
}
?>

Beachte bei den Cases 6 und 7: Ohne break nach Case 6 werden beide Fälle zusammengefasst. Dieses Fallthrough-Verhalten ist gewollt und erlaubt es, mehrere Werte mit demselben Code zu behandeln.

Alternative Syntax mit Doppelpunkt

Innerhalb von HTML-Templates kann die alternative Syntax mit switch: und endswitch; die Lesbarkeit verbessern:

<?php switch ($rolle): ?>

<?php case 'admin': ?>
<p>Adminbereich</p>
<?php break; ?>
<?php case 'user': ?>
<p>Benutzerbereich</p>
<?php break; ?>
<?php default: ?>
<p>Gastzugang</p>
<?php endswitch; ?>

switch im Detail: Datentypen und lose Vergleiche

Ein häufiger Stolperstein bei switch ist der lose Typvergleich mit dem Operator ==. PHP wandelt dabei Werte automatisch um, was zu unerwarteten Treffern führen kann:

<?php

$wert = 0;

switch ($wert) {
case 'text':
echo 'Unerwarteter Treffer!';
break;
case 0:
echo 'Korrekt: Null';
break;
}
/* Ausgabe: "Unerwarteter Treffer!"
Grund: 0 == 'text' ist true
(loser Vergleich) */
?>

Dieses Verhalten betrifft besonders den Vergleich von Ganzzahlen mit Strings. Seit PHP 8.0 wurde der lose Vergleich zwischen 0 und nicht-numerischen Strings zwar geändert (0 == "text" ist jetzt false), bei älteren PHP-Versionen bleibt das Problem aber bestehen. Wer eine korrekte Typ-Handhabung sicherstellen will, sollte den match-Ausdruck verwenden.

PHP switch vs. if-elseif-else

Wann lohnt sich switch gegenüber if-elseif? Die Antwort hängt von der Art der Bedingungen ab:

Kriteriumif-elseif-elseswitch
VergleichBeliebige BedingungenEin Ausdruck gegen feste Werte
LesbarkeitGut bei 2–3 FällenBesser ab 4+ Fällen
FallthroughNicht möglichOhne break möglich
TypvergleichFrei wählbar (==, ===)Immer loser Vergleich (==)
RückgabewertNein (Anweisung)Nein (Anweisung)

Zusammengefasst: Wenn ein einzelner Wert gegen viele Möglichkeiten geprüft wird, ist switch übersichtlicher. Sobald unterschiedliche Bedingungen geprüft werden (zum Beispiel Bereichsprüfungen oder verschiedene Variablen), ist if-elseif die bessere Wahl.

Die moderne Alternative: match (PHP 8.0+)

Seit PHP 8.0 gibt es den match-Ausdruck. Im Gegensatz zu switch ist match ein Ausdruck mit Rückgabewert, vergleicht strikt mit === und kennt kein Fallthrough.

Syntax und Rückgabewert

Die kompakte Syntax macht match besonders für Zuweisungen attraktiv:

<?php

$status = 404;

$meldung = match ($status) {
200 => 'OK',
301 => 'Moved Permanently',
404 => 'Not Found',
500 => 'Internal Server Error',
default => 'Unbekannter Status',
};

echo $meldung; // Not Found
?>

Der gesamte match-Block gibt einen Wert zurück, der direkt einer Variablen zugewiesen oder in einem Funktionsaufruf verwendet werden kann. Jeder Arm besteht aus einem oder mehreren Vergleichswerten, gefolgt von => und dem Rückgabewert. Mehrere Werte pro Arm werden durch Kommas getrennt:

<?php

$code = 302;

$typ = match (true) {
$code >= 200 && $code < 300 => 'Erfolg',
$code >= 300 && $code < 400 => 'Weiterleitung',
$code >= 400 && $code < 500 => 'Client-Fehler',
$code >= 500 => 'Server-Fehler',
default => 'Unbekannt',
};

echo $typ; // Weiterleitung
?>

UnhandledMatchError verstehen

Was passiert, wenn kein Arm zutrifft und kein default definiert ist? PHP wirft einen UnhandledMatchError:

<?php

$farbe = 'gelb';

/* Kein passender Arm, kein default
=> UnhandledMatchError */
$hex = match ($farbe) {
'rot' => '#FF0000',
'gruen' => '#00FF00',
'blau' => '#0000FF',
};
?>

Dieser Fehler ist kein Bug, sondern ein Sicherheitsmerkmal. Bei switch ohne default passiert einfach nichts, was schwer zu findende Logikfehler verursachen kann. match erzwingt dagegen eine bewusste Entscheidung: Entweder alle Fälle abdecken oder einen default-Arm definieren.

<?php

/* Sicherer Umgang mit
UnhandledMatchError */
try {
$ergebnis = match ($eingabe) {
'a' => 'Alpha',
'b' => 'Beta',
};
} catch (\UnhandledMatchError $e) {
$ergebnis = 'Unbekannt';
error_log('Unbehandelter Wert: '
. $eingabe);
}
?>

match mit komplexen Ausdrücken

Die Arme eines match-Ausdrucks können mehr als einfache Literale enthalten. Mit match(true) lassen sich beliebige Bedingungen prüfen, ähnlich wie bei if-elseif, aber kompakter:

<?php

$alter = 25;

$kategorie = match (true) {
$alter < 13 => 'Kind',
$alter < 18 => 'Jugendlicher',
$alter < 65 => 'Erwachsener',
default => 'Senior',
};

echo $kategorie; // Erwachsener
?>

Auch Callbacks und Funktionsaufrufe sind als Rückgabewerte möglich. Das ermöglicht ein elegantes Dispatch-Pattern:

<?php

$aktion = 'speichern';

$handler = match ($aktion) {
'speichern' => fn() => speichereDaten(),
'loeschen' => fn() => loescheDaten(),
'exportieren' => fn() => exportiereDaten(),
default => fn() => zeigeHilfe(),
};

$handler(); // Ruft speichereDaten() auf
?>

Vergleichsübersicht: if-elseif vs. switch vs. match

Die folgende Tabelle fasst die drei Kontrollstrukturen zusammen und hilft bei der Entscheidung:

Merkmalif-elseifswitchmatch
PHP-VersionAlleAlleAb 8.0
TypAnweisungAnweisungAusdruck
RückgabewertNeinNeinJa
VergleichFrei wählbarLose (==)Strikt (===)
FallthroughNicht möglichJa (ohne break)Nicht möglich
Mehrere WerteMit ||Gestapelte CasesKommagetrennt
Kein Trefferelse oder nichtsdefault oder nichtsdefault oder Fehler
Side-EffectsJaJaNur im Rückgabewert

Migration: Von switch zu match

Bestehenden switch-Code auf match umzuschreiben ist in vielen Fällen unkompliziert. Hier ist eine Schritt-für-Schritt-Anleitung anhand eines konkreten Beispiels:

Vorher: switch

<?php

$dateiendung = 'jpg';

switch ($dateiendung) {
case 'jpg':
case 'jpeg':
case 'png':
case 'gif':
$typ = 'Bild';
break;
case 'mp4':
case 'avi':
$typ = 'Video';
break;
case 'pdf':
$typ = 'Dokument';
break;
default:
$typ = 'Unbekannt';
break;
}

echo $typ; // Bild
?>

Nachher: match

<?php

$dateiendung = 'jpg';

$typ = match ($dateiendung) {
'jpg', 'jpeg', 'png', 'gif' => 'Bild',
'mp4', 'avi' => 'Video',
'pdf' => 'Dokument',
default => 'Unbekannt',
};

echo $typ; // Bild
?>

Schritt für Schritt

So gehst du bei der Umstellung vor:

  1. Rückgabewert identifizieren: Wenn jeder case-Block eine Variable setzt oder einen Wert zurückgibt, eignet sich match besonders gut.
  2. break entfernen: match kennt kein Fallthrough, daher wird break nicht benötigt.
  3. Gestapelte Cases zusammenfassen: Mehrere case-Zeilen ohne eigenen Code werden zu kommaseparierten Werten in einem match-Arm.
  4. Typvergleich beachten: match vergleicht strikt (===). Stelle sicher, dass die Datentypen übereinstimmen. Wenn $status ein String "200" ist, trifft 200 => ... nicht mehr zu.
  5. Side-Effects prüfen: Wenn ein case-Block mehr tut als einen Wert zuzuweisen (zum Beispiel Datenbankabfragen oder Dateioperationen), ist switch oft die bessere Wahl.

Enum und match: Typsichere Fallunterscheidung (PHP 8.1+)

Seit PHP 8.1 gibt es Enumerations (Enums), die sich hervorragend mit match kombinieren lassen. Diese Kombination ermöglicht typsichere Fallunterscheidungen, bei denen der Code sofort signalisiert, wenn ein Enum-Wert nicht behandelt wurde.

Backed Enums mit match

Ein Backed Enum ordnet jedem Fall einen skalaren Wert zu. Zusammen mit match ergibt sich ein besonders kompaktes Pattern:

<?php

enum HttpStatus: int {
case OK = 200;
case NotFound = 404;
case ServerError = 500;
}

function beschreibeStatus(
HttpStatus $status
): string {
return match ($status) {
HttpStatus::OK
=> 'Anfrage erfolgreich',
HttpStatus::NotFound
=> 'Seite nicht gefunden',
HttpStatus::ServerError
=> 'Interner Serverfehler',
};
}

$s = HttpStatus::NotFound;
echo beschreibeStatus($s);
// Seite nicht gefunden
?>

Der besondere Vorteil: Weil das Enum genau drei Fälle definiert und alle drei im match abgedeckt sind, wird kein default benötigt. Fügt jemand später einen neuen Enum-Fall hinzu (zum Beispiel Forbidden = 403), wirft PHP automatisch einen UnhandledMatchError. So werden vergessene Fälle sofort sichtbar.

Benutzerrollen mit Pure Enum

Auch ohne skalare Werte funktioniert die Kombination. Pure Enums eignen sich besonders für Rollen und Berechtigungen:

<?php

enum Rolle {
case Admin;
case Redakteur;
case Benutzer;
case Gast;
}

function darfBearbeiten(Rolle $r): bool
{
return match ($r) {
Rolle::Admin,
Rolle::Redakteur => true,
Rolle::Benutzer,
Rolle::Gast => false,
};
}

echo darfBearbeiten(Rolle::Redakteur)
? 'Ja' : 'Nein'; // Ja
?>

Verglichen mit einem switch auf Strings wie 'admin' oder 'user' bietet die Enum-Variante zwei Vorteile: Tippfehler fallen beim Kompilieren auf, und die IDE kann automatisch alle Enum-Fälle vorschlagen.

Praxisbeispiele

Die folgenden Beispiele zeigen switch und match in realistischen Szenarien und machen deutlich, wann welche Kontrollstruktur ihre Stärken ausspielt.

HTTP-Router mit match

Ein einfacher Router ordnet HTTP-Methode und Pfad einem Handler zu. Mit match lässt sich das besonders kompakt formulieren:

<?php

$method = $_SERVER['REQUEST_METHOD'];
$path = parse_url(
$_SERVER['REQUEST_URI'],
PHP_URL_PATH
);

$handler = match (true) {
$method === 'GET'
&& $path === '/'
=> 'showHome',
$method === 'GET'
&& $path === '/kontakt'
=> 'showKontakt',
$method === 'POST'
&& $path === '/kontakt'
=> 'handleKontakt',
$method === 'GET'
&& $path === '/impressum'
=> 'showImpressum',
default => 'show404',
};

/* Ruft die Handler-Funktion auf */
echo $handler();
?>

Hier zeigt sich die Stärke von match(true): Es kombiniert mehrere Bedingungen pro Arm und gibt trotzdem einen sauberen Rückgabewert zurück. Mit switch bräuchte man dafür verschachtelte if-Abfragen innerhalb der Cases.

State Machine mit switch

Für eine State Machine, die den Zustand eines Objekts verwaltet und Übergänge steuert, ist switch besser geeignet. Der Grund: Es geht nicht um einen Rückgabewert, sondern um Zustandswechsel mit Seiteneffekten.

<?php

function bestellungWeiterleiten(
string &$status
): string {
switch ($status) {
case 'neu':
$status = 'bezahlt';
return 'Zahlung eingegangen.';

case 'bezahlt':
$status = 'versendet';
versandMailSenden();
return 'Paket versendet.';

case 'versendet':
$status = 'geliefert';
return 'Zustellung bestätigt.';

case 'geliefert':
return 'Bestellung abgeschlossen.';

default:
return 'Ungültiger Status.';
}
}

$status = 'neu';
echo bestellungWeiterleiten($status);
// Zahlung eingegangen.
echo ' Status: ' . $status;
// Status: bezahlt
?>

In diesem Beispiel ändert jeder Case den Zustand und führt zusätzliche Aktionen aus (wie den Mailversand). Mit match wäre das umständlicher, weil match auf Rückgabewerte ausgelegt ist und Side-Effects in den Armen vermieden werden sollten.

Best Practices

Die folgenden Empfehlungen helfen, typische Fehler zu vermeiden und den richtigen Einsatz von switch und match sicherzustellen:

  • match für Wertzuweisungen: Wenn das Ergebnis einer Variable zugewiesen oder direkt zurückgegeben wird, ist match die sauberere Wahl.
  • switch für Side-Effects: Wenn jeder Fall eine Aktion auslöst (Datenbank, Mailversand, Logging), passt switch besser.
  • Immer default definieren: Bei switch verhindert ein default-Block stilles Durchfallen. Bei match verhindert er den UnhandledMatchError in Fällen, wo nicht alle möglichen Werte bekannt sind.
  • Bei Enums kein default: Wenn ein match alle Enum-Fälle abdeckt, ist ein default unerwünscht. So zeigt PHP automatisch an, wenn ein neuer Enum-Fall hinzukommt.
  • Fallthrough dokumentieren: Absichtliches Fallthrough in switch sollte mit einem Kommentar wie /* Fallthrough */ gekennzeichnet werden.
  • Kurze Arme bevorzugen: Wenn ein match-Arm oder case-Block länger als 5 Zeilen wird, ist eine ausgelagerte Funktion übersichtlicher.

Häufige Fehler und Debugging-Tipps

Die folgende Übersicht zeigt die häufigsten Stolpersteine bei switch und match und wie man sie löst:

FehlerUrsacheLösung
Falscher Case trifft zuLoser Vergleich bei switchmatch verwenden oder Typen vorher casten
UnhandledMatchErrorKein passender Arm, kein defaultdefault-Arm ergänzen oder alle Werte abdecken
Code läuft in nächsten Casebreak vergessen bei switchbreak am Ende jedes Case-Blocks setzen
match-Arm wird nie erreichtTyp-Mismatch (z.B. "1" vs 1)Typen prüfen, match nutzt === (strikt)
Syntax-Fehler bei matchSemikolon statt Komma nach ArmArme mit Komma trennen, Semikolon nur am Ende

Performance: switch vs. match

Eine häufige Frage lautet: Ist match schneller als switch? Ein einfacher Benchmark gibt Aufschluss:

<?php

$wert = 'c';
$durchlaeufe = 1_000_000;

/* Benchmark: switch */
$start = microtime(true);
for ($i = 0; $i < $durchlaeufe; $i++) {
switch ($wert) {
case 'a': $r = 1; break;
case 'b': $r = 2; break;
case 'c': $r = 3; break;
case 'd': $r = 4; break;
default: $r = 0; break;
}
}
$switchZeit = microtime(true) - $start;

/* Benchmark: match */
$start = microtime(true);
for ($i = 0; $i < $durchlaeufe; $i++) {
$r = match ($wert) {
'a' => 1,
'b' => 2,
'c' => 3,
'd' => 4,
default => 0,
};
}
$matchZeit = microtime(true) - $start;

printf("switch: %.4f s\n", $switchZeit);
printf("match: %.4f s\n", $matchZeit);
/* Typisches Ergebnis (PHP 8.3):
switch: 0.0180 s
match: 0.0165 s */
?>

In der Praxis sind die Unterschiede minimal. Beide Kontrollstrukturen liegen im selben Bereich, wobei match in manchen PHP-Versionen einen kleinen Vorsprung hat. Die Wahl sollte nicht von der Performance abhängen, sondern von Lesbarkeit, Typsicherheit und dem konkreten Anwendungsfall.

Interaktives Beispiel

Das folgende Beispiel kombiniert switch, match und if-elseif in einem Programm. Es liest eine Zahl und gibt verschiedene Informationen darüber aus:

<?php

function leseZahl(): int|false
{
echo "Gib eine Zahl ein (1-10): ";
$eingabe = trim(fgets(STDIN));

if (!ctype_digit($eingabe)) {
return false;
}
return (int)$eingabe;
}

$zahl = leseZahl();

if ($zahl === false) {
echo "Ungültige Eingabe!\n";
exit(1);
}

/* match: Zahl in Wort umwandeln */
$wort = match ($zahl) {
1 => 'eins', 2 => 'zwei',
3 => 'drei', 4 => 'vier',
5 => 'fuenf', 6 => 'sechs',
7 => 'sieben', 8 => 'acht',
9 => 'neun', 10 => 'zehn',
default => 'ausserhalb',
};

/* match(true): Groessenordnung */
$groesse = match (true) {
$zahl <= 3 => 'klein',
$zahl <= 6 => 'mittel',
$zahl <= 10 => 'gross',
default => 'riesig',
};

/* switch: Detailbeschreibung */
switch ($zahl) {
case 1:
$info = 'Die kleinste natürliche Zahl';
break;
case 7:
$info = 'Glückszahl in vielen Kulturen';
break;
case 10:
$info = 'Basis des Dezimalsystems';
break;
default:
$info = 'Keine besondere Bedeutung';
break;
}

echo "$zahl ($wort) ist $groesse.\n";
echo "Info: $info\n";
echo 'Gerade: '
. ($zahl % 2 === 0 ? 'Ja' : 'Nein');
?>

Fazit

PHP bietet mit switch und match zwei leistungsfähige Kontrollstrukturen für Fallunterscheidungen. switch ist seit Jahrzehnten bewährt und eignet sich besonders für Szenarien mit Side-Effects, Fallthrough-Logik oder älteren PHP-Versionen. match bringt seit PHP 8.0 strikte Typvergleiche, einen Rückgabewert und kompaktere Syntax mit. Wer PHP 8.1+ nutzt, profitiert zusätzlich von der Kombination mit Enums.

Die Faustregel: Für reine Wertzuweisungen match, für komplexe Abläufe mit mehreren Anweisungen switch, und für unterschiedliche Bedingungen if-elseif. In modernem PHP-Code wird match immer häufiger eingesetzt und sollte die erste Wahl sein, wenn die Anforderungen es erlauben.

Weiterführende Ressourcen

Häufige Fragen (FAQ)

Kann ich switch und match in derselben Funktion mischen?

Ja, das ist möglich und manchmal sinnvoll. Verwende match für die Wertzuweisung und switch für die anschliessende Verarbeitung mit Side-Effects.

Funktioniert match mit Objekten?

Ja. match vergleicht Objekte mit ===, was bei Objekten auf Identität prüft (gleiche Instanz). Zwei verschiedene Objekte mit identischen Werten sind nicht === gleich. Ausnahme: Enums, bei denen === den Enum-Wert vergleicht.

Ersetzt match die switch-Anweisung komplett?

Nein. match ist kein Ersatz, sondern eine Ergänzung. Für Fallthrough-Logik, Side-Effects und Szenarien ohne Rückgabewert bleibt switch die richtige Wahl.

Wie viele Arme kann ein match-Ausdruck haben?

Es gibt kein technisches Limit. Ab etwa 10 bis 15 Armen sollte man aber überlegen, ob ein Array-Lookup, eine Datenbanktabelle oder ein Strategy-Pattern die bessere Lösung ist.

 

Tags:

 

Bücherregal mit drei Büchern: 'PHP 4 - Grundlagen und Profiwissen' von Hanser Verlag, 'Webdesign in a Nutshell' von O'Reilly Verlag, und 'Webgestaltung' von Galileo Computing.