Mappa bejárása: PHP glob() függvény

Még mindig a jó öreg opendir() függvényt használod, hogy bejárj egy könyvtárat PHP segítségével? Van ennél egy sokkal okosabb megoldás, a PHP glob() függvénye.

Egyrészt jóval gyorsabb, másrészt feleannyi kóddal elérheted ugyanazt az eredményt.

$dir = "/etc/php5/";
// megnyitunk egy mappát és beolvassuk a tartalmát
if (is_dir($dir))
{
	if ($dh = opendir($dir))
	{
		while (($file = readdir($dh)) !== false)
		{
			echo "fájlnév: $file : fájltípus: " . filetype($dir . $file) . "n";
		}
		closedir($dh);
	}
}

A fenti kódot nagy mértékben lerövidíthetjük a következő módon:

$dir = "/etc/php5/*";
 
// megnyitunk egy mappát és beolvassuk a tartalmát
foreach(glob($dir) as $file)
{
	echo "fájlnév: $file : fájltípus: " . filetype($file) . "<br />";
}

Glob() függvény első paramétere

Az első paraméter egy mintát vár, aminek segítségével szűkíthetjük a keresett fájlok típusát, illetve több mappát is bejárhatunk a “*” joker karakter segítségével. Tegyük fel, hogy van egy oldal ahol a felhasználók képeket tölthetnek fel. Mindegyiknek van saját mappája a userImages mappán belül. Ezeken a mappákon belül van két másik mappa: HD és TN, a teljes méretű és az előnézeti képeknek. Tegyük fel, hogy az összes felhasználó előnézeti képeinek ki szeretnéd iratni a nevét. Opendir() paranccsal elég hosszú kódot kellene írnunk, viszont a glob() segítségével sokkal egyszerűbb:

foreach(glob('userImages/*/TN/*') as $image)
{
	echo "Fájl név: " . $image . "<br />";
}

A fenti kód visszaadja a userImages/*/TN/* -re illeszkedő fájlokat.

Fájl név: userImages/username1/TN/test.jpg  
Fájl név: userImages/username1/TN/test3.jpg  
Fájl név: userImages/username1/TN/test5.png  
Fájl név: userImages/username2/TN/subfolder  
Fájl név: userImages/username2/TN/test2.jpg  
Fájl név: userImages/username2/TN/test4.gif  
Fájl név: userImages/username3/TN/styles.css

Egyel továbbléphetünk, és konkrétan megmondhatjuk milyen kiterjesztésű fájlokat keressen:

foreach(glob('userImages/*/TN/*.jpg') as $image)
{
	echo "Fájl név: " . $image . "<br />";
}

Így már csak a JPEG fájlokat kapjuk vissza.

Fájl név: userImages/username1/TN/test.jpg  
Fájl név: userImages/username1/TN/test3.jpg  
Fájl név: userImages/username2/TN/test2.jpg

A lényeg még csak ezután jön. Mi van ha nem csak a JPEG hanem GIF fájlokra is szükséged van? Vagy ha csak mappák neveit akarod kiiratni? Itt jön képbe a második paraméter.

Mappa bejárás második paramétere

A második paraméter opcionális, viszont egy rakás flaget tartalmaz amivel megváltoztathatod a glob() viselkedését.

  • GLOB_MARK: Minden illeszkedő mappa végére tesz egy per jelet
  • GLOB_NOSORT: Olyan sorrendben jeleníti meg a fájlokat, ahogy a mappában vannak, rendezés nélkül
  • GLOB_NOCHECK: Visszaadja a mintát ha nem illeszkedett rá semmi
  • GLOB_NOESCAPE: A backslash-el nem lehet speciális karakterekt írni (pl t “)
  • GLOB_BRACE: {a,b,c}-t úgy értelmezi, hogy illeszkedjen ‘a’-ra ‘b’-re vagy ‘c’-re
  • GLOB_ONLYDIR: Csak azokat a mappákat adja vissza amik illeszkednek a mintára
  • GLOB_ERR: Álljon meg olvasási hibánál (nem olvasható mappa), alapból a hibákat figyelmen kívül hagyja

Így már megoldható a fenti probléma, csak a GLOB_BRACE flaget kell használnunk:

foreach(glob('userImages/*/TN/{*.jpg,*.gif}',GLOB_BRACE) as $image)
{
	echo "Fájl név: " . $image . "<br />";
}

Ami visszaadja

Fájl név: userImages/username1/TN/test.jpg  
Fájl név: userImages/username1/TN/test3.jpg  
Fájl név: userImages/username2/TN/test2.jpg  
Fájl név: userImages/username2/TN/test4.gif

Ha csak az almappák nevét akarjuk kiiratni, a GLOB_ONLYDIR flaget használjuk:

foreach(glob('userImages/*/TN/*',GLOB_ONLYDIR ) as $image)
{
	echo "Fájl név: " . $image . "<br />";
}

Aminek eredménye:

Fájl név: userImages/username2/TN/subfolder

Összegzés

Érdekes módon a PHP glob() függvény nem tartozik a legismertebbek közé, de te is láthatod mennyivel hatékonyabb, mint más módszerek. Én személy szerint pluginok importálásához szoktam használni:

foreach(glob('includes/plugins/*.php') as $plugin)
{
	include_once($plugin);
}

Frissítés:

Szatmári.hu írta:
GLOB_BRACE nem műxik minden oprendszeren ezért:
foreach (array_merge((array)glob(“$dir/*.jpg”), (array)glob(“$dir/*.gif”)) as $image);
Az (array) azért kell, hogy ne legyen hiba a tömbök összefűzésénél (ha nincs ilyen egy fájlformátum)

Köszi a plusz infót!