W3docs

fnmatch()

Die Funktion fnmatch() in PHP prüft, ob ein string einem Shell-Wildcard-Muster entspricht. Ideal zum Filtern von Dateinamen ohne reguläre Ausdrücke.

Was ist die fnmatch()-Funktion?

Die Funktion fnmatch() prüft, ob ein string einem Shell-Wildcard-Muster entspricht — genau der Art von Muster, die man in einem Terminal eingibt, wie *.txt oder image-?.png. Sie gibt einen boolean-Wert zurück und wird daher am häufigsten verwendet, um Dateinamen oder andere Zeichenketten zu filtern, ohne einen vollständigen regulären Ausdruck schreiben zu müssen.

Trotz des Namens greift fnmatch() niemals auf das Dateisystem zu. Sie vergleicht das Muster lediglich mit dem übergebenen string, funktioniert also mit beliebigem Text — nicht nur mit echten Dateien.

Diese Seite behandelt die Signatur der Funktion, die unterstützten Wildcard-Zeichen, die optionalen Flags sowie die praktischen Einsatzfälle, in denen sie sowohl glob() als auch regulären Ausdrücken überlegen ist.

Syntax

fnmatch(string $pattern, string $filename, int $flags = 0): bool
  • $pattern — das Shell-Wildcard-Muster, gegen das geprüft wird.
  • $filename — der zu testende string (muss keine echte Datei sein).
  • $flags — optionale Bit-Flags, die das Matching-Verhalten ändern (siehe Flags).

Die Funktion gibt true zurück, wenn $filename mit $pattern übereinstimmt, andernfalls false.

Einfaches Beispiel

php— editable, runs on the server

Hier stimmt myfile.txt mit *.txt überein, sodass der erste Zweig ausgeführt wird und The string matches the pattern! ausgegeben wird. Ändert man den string zu myfile.csv, schlägt die Übereinstimmung fehl.

Wildcard-Zeichen

fnmatch() versteht die standardmäßigen Shell-Wildcards. Zu wissen, was jedes Zeichen genau bedeutet, ist der Schlüssel zur korrekten Verwendung der Funktion:

WildcardBedeutungBeispielmusterTrifft zuTrifft nicht zu
*Beliebige Zeichenfolge (auch leer)*.logerror.log, .logerror.txt
?Genau ein Zeichenfile?.txtfile1.txtfile12.txt
[...]Ein Zeichen aus der Mengeimage.[jp]ngimage.jng, image.pngimage.gng
[!...]Ein Zeichen nicht in der Menge[!0-9]*abc1abc

Das folgende Beispiel zeigt jeden Wildcard-Typ nebeneinander:

<?php

var_dump(fnmatch("*.log", "error.log"));     // bool(true)  — * matches "error"
var_dump(fnmatch("file?.txt", "file1.txt")); // bool(true)  — ? matches one char
var_dump(fnmatch("file?.txt", "file12.txt"));// bool(false) — ? matches only ONE char
var_dump(fnmatch("img.[jp]ng", "img.png"));  // bool(true)  — p is in [jp]
var_dump(fnmatch("[!0-9]*", "abc"));          // bool(true)  — first char is not a digit
var_dump(fnmatch("[!0-9]*", "1abc"));         // bool(false) — first char IS a digit

Flags

Das dritte Argument akzeptiert eine oder mehrere der folgenden Konstanten, die mit dem bitweisen OR-Operator (|) kombiniert werden können:

FlagWirkung
FNM_NOESCAPEBehandelt einen Backslash (\) als wörtliches Zeichen statt als Escape-Zeichen.
FNM_PATHNAMEEin Schrägstrich (/) im string muss durch ein wörtliches / abgeglichen werden — * und ? stimmen nicht damit überein.
FNM_PERIODEin führender Punkt im string muss explizit abgeglichen werden; * und ? stimmen nicht damit überein.
FNM_CASEFOLDGroß-/Kleinschreibung wird beim Abgleich ignoriert.

FNM_CASEFOLD ist das Flag, das man am häufigsten benötigt:

<?php

var_dump(fnmatch("*.PNG", "photo.png"));               // bool(false) — case differs
var_dump(fnmatch("*.PNG", "photo.png", FNM_CASEFOLD)); // bool(true)  — case ignored

Mit FNM_PATHNAME stoppt der Wildcard * an Verzeichnistrennzeichen, was beim Abgleichen ganzer Pfade nützlich ist:

<?php

var_dump(fnmatch("src/*.php", "src/index.php"));               // bool(true)
var_dump(fnmatch("src/*.php", "src/lib/db.php"));              // bool(true)  — * crosses the slash
var_dump(fnmatch("src/*.php", "src/lib/db.php", FNM_PATHNAME));// bool(false) — * cannot cross "/"

Ein praktischer Anwendungsfall: Eine Dateiliste filtern

Eine häufige Aufgabe besteht darin, nur die Einträge zu behalten, die einem Muster entsprechen. Da fnmatch() mit einfachen Zeichenketten arbeitet, lässt es sich gut mit array_filter() kombinieren:

<?php

$files = ["report.pdf", "notes.txt", "draft.txt", "image.png"];

$textFiles = array_filter($files, fn($file) => fnmatch("*.txt", $file));

print_r(array_values($textFiles));

Dies gibt aus:

Array
(
    [0] => notes.txt
    [1] => draft.txt
)

fnmatch() vs. glob() vs. Reguläre Ausdrücke

Diese drei Werkzeuge überschneiden sich, daher ist die richtige Wahl entscheidend:

  • Verwende glob(), wenn du echte Dateien von der Festplatte lesen möchtest, die einem Muster entsprechen. Sie greift auf das Dateisystem zu und gibt die passenden Pfade zurück.
  • Verwende fnmatch(), wenn du bereits Zeichenketten (Dateinamen, Schlüssel, Labels) im Speicher hast und nur eine true/false-Prüfung gegen ein Wildcard-Muster benötigst.
  • Verwende preg_match(), wenn du die volle Leistungsfähigkeit regulärer Ausdrücke benötigst — Capture-Gruppen, Alternativen, Quantoren —, die einfache Wildcards nicht ausdrücken können.

Häufige Fallstricke

  • Kein Dateisystemzugriff. fnmatch() prüft nicht, ob eine Datei existiert; sie vergleicht nur Zeichenketten. Für den Festplattenzugriff verwende glob().
  • Verfügbarkeit. Bei Windows-Builds vor PHP 7.2 kann fnmatch() nicht verfügbar sein. Umhülle Aufrufe mit function_exists('fnmatch'), wenn du diese Umgebungen unterstützen musst.
  • Muster sind keine regulären Ausdrücke. * bedeutet „beliebige Zeichen", nicht „null oder mehr des vorherigen Tokens". Wer a+ schreibt und einen Regex-Quantor erwartet, erhält stattdessen die zwei wörtlichen Zeichen a und +.
  • Versteckte Dateien. Standardmäßig stimmt * mit einem führenden Punkt überein, sodass * auch .gitignore trifft. Füge FNM_PERIOD hinzu, wenn du Dotfiles so überspringen möchtest wie eine Shell.

Fazit

fnmatch() ist der einfachste Weg, in PHP einen string gegen ein Shell-artiges Wildcard-Muster zu testen. Greife darauf zurück, wenn du schnelles, lesbares Dateiname-Filtern ohne den Aufwand eines regulären Ausdrucks benötigst — und denke an ihre Begleiter glob() zum Lesen von Dateien von der Festplatte und preg_match() für alles, was komplexer als Wildcards ist.

Übung

Übung
Was sind die Argumente der fnmatch()-Funktion in PHP?
Was sind die Argumente der fnmatch()-Funktion in PHP?
Was this page helpful?