Start · Sprachen · PHP · Referenz · fnmatch

fnmatch

Funktion

Vergleicht einen Dateinamen (oder beliebigen String) mit einem Shell-Platzhaltermuster (Glob-Muster) und gibt <code>true</code> zurück, wenn der String übereinstimmt.

seit PHP 4.3.0 Kategorie: io

Signatur

fnmatch(string $pattern, string $filename, int $flags = 0): bool

Beschreibung

fnmatch() prüft, ob ein gegebener String einem Shell-Platzhaltermuster entspricht, wie es z. B. bei Dateinamen-Globbing in der Kommandozeile üblich ist. Das Muster kann die Sonderzeichen * (beliebige Zeichenfolge), ? (genau ein Zeichen) sowie Zeichenklassen in eckigen Klammern ([abc], [a-z]) enthalten.

Die Funktion ist besonders nützlich, wenn aus einer Liste von Dateinamen oder Pfaden diejenigen herausgefiltert werden sollen, die einem bestimmten Muster entsprechen – beispielsweise alle Dateien mit der Endung .php oder alle Dateien, die mit einem bestimmten Präfix beginnen. Sie kann aber auch für beliebige Strings verwendet werden, nicht nur für echte Dateisystempfade.

Mit dem optionalen $flags-Parameter lässt sich das Verhalten anpassen, z. B. können Schrägstriche in der Übereinstimmung einbezogen oder die Groß-/Kleinschreibung ignoriert werden. Auf Windows-Systemen ist fnmatch() erst ab PHP 5.3.0 verfügbar.

Im Gegensatz zu regulären Ausdrücken bietet fnmatch() eine einfachere, für Dateimuster optimierte Syntax, die gut lesbar und wartbar ist.

Parameter

Name Typ Default Beschreibung
$pattern Pflicht string Das Shell-Platzhaltermuster. Sonderzeichen: * steht für beliebig viele Zeichen, ? für genau ein Zeichen, [...] für eine Zeichenklasse, \ als Escape-Zeichen (sofern nicht FNM_NOESCAPE gesetzt).
$filename Pflicht string Der zu prüfende String (typischerweise ein Dateiname oder Pfad), der gegen das Muster verglichen wird.
$flags int 0 Bitmaske aus folgenden Konstanten: FNM_NOESCAPE – Backslash wird nicht als Escape-Zeichen behandelt; FNM_PATHNAME – Schrägstriche werden nur durch Schrägstriche im Muster gematcht; FNM_PERIOD – ein führender Punkt muss explizit im Muster stehen; FNM_CASEFOLD – Groß-/Kleinschreibung ignorieren (nur auf einigen Systemen verfügbar).

Rückgabewert

Typ
bool
Beschreibung
Gibt true zurück, wenn $filename dem Muster $pattern entspricht, andernfalls false.

Beispiele

Einfaches Dateiendungs-Matching

<?php
$dateien = ['index.php', 'style.css', 'script.js', 'config.php', 'README.md'];

foreach ($dateien as $datei) {
    if (fnmatch('*.php', $datei)) {
        echo $datei . ' ist eine PHP-Datei.' . PHP_EOL;
    }
}
index.php ist eine PHP-Datei. config.php ist eine PHP-Datei.

Muster mit Fragezeichen und Zeichenklasse

<?php
$namen = ['file1.txt', 'file2.txt', 'file10.txt', 'File3.txt', 'data1.txt'];

foreach ($namen as $name) {
    // Genau ein Zeichen nach 'file', dann '.txt'
    if (fnmatch('file?.txt', $name)) {
        echo $name . ' passt zum Muster.' . PHP_EOL;
    }
}
file1.txt passt zum Muster. file2.txt passt zum Muster.

Groß-/Kleinschreibung ignorieren mit FNM_CASEFOLD

<?php
$dateien = ['Index.PHP', 'style.CSS', 'script.JS', 'config.php'];

foreach ($dateien as $datei) {
    if (fnmatch('*.php', $datei, FNM_CASEFOLD)) {
        echo $datei . ' erkannt (case-insensitiv).' . PHP_EOL;
    }
}
Index.PHP erkannt (case-insensitiv). config.php erkannt (case-insensitiv).

Pfade mit FNM_PATHNAME korrekt prüfen

<?php
// Ohne FNM_PATHNAME: * matcht auch Schrägstriche
var_dump(fnmatch('src/*.php', 'src/lib/helper.php'));           // true (unerwünscht)

// Mit FNM_PATHNAME: * matcht KEINE Schrägstriche
var_dump(fnmatch('src/*.php', 'src/lib/helper.php', FNM_PATHNAME)); // false
var_dump(fnmatch('src/*.php', 'src/index.php', FNM_PATHNAME));      // true
bool(true) bool(false) bool(true)

// Wichtig · Fallstricke

Plattformverfügbarkeit: Auf Windows-Systemen ist fnmatch() erst seit PHP 5.3.0 verfügbar, da die zugrundeliegende C-Bibliotheksfunktion dort nicht nativ existiert und von PHP selbst implementiert wurde.

Keine Dateisystem-Interaktion: fnmatch() liest das Dateisystem nicht aus – es vergleicht ausschließlich Strings. Um alle passenden Dateien aus einem Verzeichnis zu finden, sollte man glob() verwenden oder fnmatch() manuell auf eine per scandir() oder DirectoryIterator ermittelte Dateiliste anwenden.

Locale-Abhängigkeit: Bei Zeichenklassen wie [a-z] kann das Ergebnis je nach gesetzter Locale variieren. Für locale-unabhängiges Verhalten sollten explizite Zeichenlisten wie [abcdefghijklmnopqrstuvwxyz] verwendet werden.