W3docs

fnmatch()

La funzione fnmatch() in PHP confronta una stringa con un pattern wildcard della shell. Scopri sintassi, caratteri wildcard, flag e casi d'uso pratici.

Cos'è la Funzione fnmatch()?

La funzione fnmatch() verifica se una stringa corrisponde a un pattern wildcard della shell — lo stesso tipo di pattern che si digita in un terminale, come *.txt o image-?.png. Restituisce un boolean, quindi viene usata principalmente per filtrare nomi di file o altre stringhe senza scrivere un'espressione regolare completa.

Nonostante il nome, fnmatch() non accede mai al filesystem. Confronta soltanto il pattern con la stringa passata, quindi funziona su qualsiasi testo, non solo su file reali.

Questa pagina illustra la firma della funzione, i caratteri wildcard riconosciuti, i flag opzionali e i casi pratici in cui è preferibile sia a glob() che alle espressioni regolari.

Sintassi

fnmatch(string $pattern, string $filename, int $flags = 0): bool
  • $pattern — il pattern wildcard della shell con cui confrontare.
  • $filename — la stringa da verificare (non deve essere un file reale).
  • $flags — flag bit opzionali che modificano il comportamento del confronto (vedi Flag).

La funzione restituisce true quando $filename corrisponde a $pattern, altrimenti false.

Esempio di Base

php— editable, runs on the server

In questo caso myfile.txt corrisponde a *.txt, quindi viene eseguito il primo ramo e viene stampato The string matches the pattern!. Sostituendo la stringa con myfile.csv, il confronto fallisce.

Caratteri Wildcard

fnmatch() riconosce i wildcard standard della shell. Sapere esattamente cosa fa ognuno è fondamentale per usare la funzione correttamente:

WildcardSignificatoPattern di esempioCorrisponde aNon corrisponde a
*Qualsiasi sequenza di caratteri (anche vuota)*.logerror.log, .logerror.txt
?Esattamente un caratterefile?.txtfile1.txtfile12.txt
[...]Un carattere dell'insiemeimage.[jp]ngimage.jng, image.pngimage.gng
[!...]Un carattere non nell'insieme[!0-9]*abc1abc

L'esempio seguente mostra ogni wildcard affiancato agli altri:

<?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

Flag

Il terzo argomento accetta una o più delle seguenti costanti, combinate con l'operatore OR bit a bit (|):

FlagEffetto
FNM_NOESCAPETratta il backslash (\) come carattere letterale invece di carattere di escape.
FNM_PATHNAMEUno slash (/) nella stringa deve essere abbinato a un / letterale — * e ? non lo abbineranno.
FNM_PERIODUn punto iniziale nella stringa deve essere abbinato esplicitamente; * e ? non lo abbineranno.
FNM_CASEFOLDConfronto senza distinzione tra maiuscole e minuscole.

FNM_CASEFOLD è il flag più usato nella pratica:

<?php

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

Con FNM_PATHNAME, il wildcard * si ferma ai separatori di directory, utile quando si confrontano percorsi completi:

<?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 "/"

Un Caso Pratico: Filtrare un Elenco di File

Un'operazione comune è mantenere solo le voci che corrispondono a un pattern. Poiché fnmatch() opera su stringhe normali, si abbina naturalmente ad array_filter():

<?php

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

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

print_r(array_values($textFiles));

Questo stampa:

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

fnmatch() vs. glob() vs. Espressioni Regolari

Questi tre strumenti si sovrappongono, quindi scegliere quello giusto è importante:

  • Usa glob() quando vuoi leggere file reali dal disco che corrispondono a un pattern. Accede al filesystem e restituisce i percorsi corrispondenti.
  • Usa fnmatch() quando hai già delle stringhe (nomi di file, chiavi, etichette) in memoria e hai bisogno solo di un controllo vero/falso rispetto a un pattern wildcard.
  • Usa preg_match() quando hai bisogno della piena potenza delle espressioni regolari — gruppi di cattura, alternanza, quantificatori — che i semplici wildcard non possono esprimere.

Attenzioni

  • Non è il filesystem. fnmatch() non verifica che un file esista; confronta solo stringhe. Per l'accesso al disco usa glob().
  • Disponibilità. Nelle versioni di Windows precedenti a PHP 7.2, fnmatch() potrebbe non essere disponibile. Racchiudi le chiamate in function_exists('fnmatch') se devi supportare quegli ambienti.
  • I pattern non sono regex. * significa "qualsiasi carattere", non "zero o più occorrenze del token precedente". Se scrivi a+ aspettandoti un quantificatore regex, viene trattato come i due caratteri letterali a e +.
  • File nascosti. Per impostazione predefinita * abbina un punto iniziale, quindi * corrisponde a .gitignore. Aggiungi FNM_PERIOD se vuoi ignorare i dotfile come fa la shell.

Conclusione

fnmatch() è il modo più semplice per verificare se una stringa corrisponde a un pattern wildcard in stile shell in PHP. Usala quando hai bisogno di un filtraggio rapido e leggibile dei nomi di file senza l'overhead di un'espressione regolare — e ricorda i suoi compagni glob() per leggere file dal disco e preg_match() per tutto ciò che è più complesso dei wildcard.

Pratica

Pratica
Quali sono gli argomenti della funzione fnmatch() in PHP?
Quali sono gli argomenti della funzione fnmatch() in PHP?
Was this page helpful?