2010-12-15 4 views
3

Dans le code correspondant de fichier typique:correspondant à des extensions de fichiers multiples avec fnmatch()

while (false !== ($file = readdir($handle))) { 
    if ($file !== "." && $file !== ".." && fnmatch($mask, $file)) { 
     $dirList[] = $file; 
    } 
} 

Je tentais d'utiliser un modèle d'extension de plusieurs fichiers comme ceci:

$mask = "*.{jpg,png,gif}"; 

mais il n'a pas travail. Aucun fichier ne correspond. C'est plutôt étrange puisque le même modèle fonctionne très bien dans un terminal. Cela fonctionne aussi parfaitement avec glob(), en retournant les fichiers que je veux. Je sais qu'il n'y a rien de mal avec le reste du code car l'utilisation de "* .jpg" comme masque fonctionne également avec fnmatch. Fnmatch n'était-il pas supposé supporter les mêmes patterns que ceux disponibles dans un shell?

Répondre

4

Ce n'est pas pris en charge. AFAIK le *.{ext,alt} est une extension ksh et bash pour globs shell. Et fnmatch() est une fonction système, mais la fonctionnalité varie selon les variantes Unix (BSD l'a, Linux/glibc ne semble pas). Il existe une constante FNM_EXTMATCH qui, selon moi, permettrait à {alt} de fonctionner. Mais PHP ne le supporte pas/le transmet.

Mais vous pouvez simplement utiliser glob() avec l'option GLOB_BRACE, qui prend en charge la correspondance .{jpeg,png,gif}. Et par ceci vous vous sauverez un readdir().

+0

* (svn) * [file.c] (http://svn.php.net/viewvc/php/php-src/trunk/ext/standard/file.c?view=markup) - pour ceux qui veux voir comment il est mis en œuvre – Gordon

+0

Intéressant. En théorie, vous pouvez passer '0x20' si votre libc supporte _EXTMATCH. – mario

+0

Merci. J'ai choisi d'utiliser glob() à la place, comme vous l'avez suggéré, car cela supporte ce dont j'ai besoin. Peut-être que dans une future version de PHP cela sera supporté via cette constante FNM_EXTMATCH. – devius

0

Votre notation Accolade est ce que je compte travailler sur bash, mais l'appel fnmatch() échoue pour moi aussi (comme le fait la suggestion de support carré). Si vous regardez la discussion sur les fenêtres de compatibilité pour cette fonction (sous sa définition) à php.net vous verrez que la notation accolade ne sont pas pris en considération pour la mise en œuvre de regex de la fonction.

+0

La notation accolade fonctionne sur bash et glob(), mais pas sur fnmatch(). Le support carré est utilisé pour correspondre uniquement des caractères individuels et non trois groupes de caractères de lettres, et qui a déjà montré sur les exemples de la section fnmatch() sur php.net. Je vais jeter un coup d'oeil à cette discussion sur les fenêtres, merci. – devius

Questions connexes