W3docs

fnmatch()

La fonction fnmatch() est une fonction PHP intégrée qui vérifie si une chaîne correspond à un motif générique de shell, utilisée pour filtrer des noms de fichiers.

Qu'est-ce que la fonction fnmatch() ?

La fonction fnmatch() vérifie si une chaîne correspond à un motif générique de shell — le même type de motif que vous tapez dans un terminal, comme *.txt ou image-?.png. Elle retourne un boolean, aussi est-elle le plus souvent utilisée pour filtrer des noms de fichiers ou d'autres chaînes sans écrire une expression régulière complète.

Malgré son nom, fnmatch() n'accède jamais au système de fichiers. Elle compare uniquement le motif à la chaîne que vous lui passez, et fonctionne donc sur n'importe quel texte, pas seulement sur de vrais fichiers.

Cette page couvre la signature de la fonction, les caractères génériques qu'elle reconnaît, les flags optionnels, ainsi que les cas pratiques où elle surpasse à la fois glob() et les expressions régulières.

Syntaxe

fnmatch(string $pattern, string $filename, int $flags = 0): bool
  • $pattern — le motif générique de shell à comparer.
  • $filename — la chaîne à tester (elle n'a pas besoin d'être un vrai fichier).
  • $flags — flags binaires optionnels qui modifient le comportement de la correspondance (voir Flags).

La fonction retourne true lorsque $filename correspond à $pattern, et false sinon.

Exemple de base

php— editable, runs on the server

Ici myfile.txt correspond à *.txt, donc la première branche s'exécute et affiche The string matches the pattern!. Remplacez la chaîne par myfile.csv et la correspondance échoue.

Caractères génériques

fnmatch() reconnaît les caractères génériques shell standard. Savoir exactement ce que fait chacun est la clé pour utiliser la fonction correctement :

Caractère génériqueSignificationExemple de motifCorrespond àNe correspond pas à
*N'importe quelle séquence de caractères (y compris aucun)*.logerror.log, .logerror.txt
?Exactement un caractèrefile?.txtfile1.txtfile12.txt
[...]Un caractère de l'ensembleimage.[jp]ngimage.jng, image.pngimage.gng
[!...]Un caractère absent de l'ensemble[!0-9]*abc1abc

L'exemple suivant illustre chaque caractère générique côte à côte :

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

Le troisième argument accepte une ou plusieurs des constantes suivantes, combinées avec l'opérateur OR binaire (|) :

FlagEffet
FNM_NOESCAPETraite une barre oblique inverse (\) littéralement plutôt que comme un caractère d'échappement.
FNM_PATHNAMEUn slash (/) dans la chaîne doit être mis en correspondance par un / littéral — * et ? ne pourront pas le faire.
FNM_PERIODUn point en début de chaîne doit être mis en correspondance explicitement ; * et ? ne pourront pas le faire.
FNM_CASEFOLDEffectue la correspondance sans tenir compte de la casse.

FNM_CASEFOLD est le flag que vous utiliserez le plus souvent :

<?php

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

Avec FNM_PATHNAME, le caractère générique * s'arrête aux séparateurs de répertoire, ce qui est pratique pour faire correspondre des chemins complets :

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

Cas pratique : filtrer une liste de fichiers

Une tâche courante consiste à ne conserver que les entrées correspondant à un motif. Comme fnmatch() fonctionne sur des chaînes simples, elle s'associe naturellement à 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));

Cela affiche :

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

fnmatch() vs. glob() vs. expressions régulières

Ces trois outils se recoupent, aussi le choix du bon outil est-il important :

  • Utilisez glob() lorsque vous souhaitez lire des fichiers réels depuis le disque correspondant à un motif. Elle accède au système de fichiers et retourne les chemins correspondants.
  • Utilisez fnmatch() lorsque vous avez déjà des chaînes (noms de fichiers, clés, étiquettes) en mémoire et que vous n'avez besoin que d'une vérification vrai/faux par rapport à un motif générique.
  • Utilisez preg_match() lorsque vous avez besoin de toute la puissance des expressions régulières — groupes de capture, alternance, quantificateurs — que les simples caractères génériques ne peuvent pas exprimer.

Pièges courants

  • Ce n'est pas le système de fichiers. fnmatch() ne vérifie pas l'existence d'un fichier ; elle compare uniquement des chaînes. Pour l'accès au disque, utilisez glob().
  • Disponibilité. Sur les versions Windows antérieures à PHP 7.2, fnmatch() peut être indisponible. Enveloppez les appels dans function_exists('fnmatch') si vous devez prendre en charge ces environnements.
  • Les motifs ne sont pas des expressions régulières. * signifie « n'importe quels caractères », et non « zéro ou plusieurs occurrences du jeton précédent ». Si vous écrivez a+ en vous attendant à un quantificateur regex, il sera traité comme les deux caractères littéraux a et +.
  • Fichiers cachés. Par défaut, * correspond à un point en début de nom, donc * correspond à .gitignore. Ajoutez FNM_PERIOD si vous souhaitez ignorer les fichiers dotfiles comme le fait un shell.

Conclusion

fnmatch() est le moyen le plus simple de tester une chaîne par rapport à un motif générique de type shell en PHP. Utilisez-la lorsque vous avez besoin d'un filtrage rapide et lisible des noms de fichiers sans la complexité d'une expression régulière — et n'oubliez pas ses compagnons glob() pour lire des fichiers depuis le disque et preg_match() pour tout ce qui est plus complexe que les caractères génériques.

Pratique

Pratique
Quels sont les arguments de la fonction fnmatch() en PHP ?
Quels sont les arguments de la fonction fnmatch() en PHP ?
Was this page helpful?