Utolsó frissítés: 2012.02.13.
Facebook Twitter iWiW MySpace Digg Delicious Google bookmarks Startlap Windows Live

Állománykezelés

A szöveges (és bármilyen egyéb) állományokkal nem csak az előző leckékben tanult műveleteket tudjuk elvégezni PHP-ből, vagyis megnyitás, bezárás, olvasás és írás. A most következő műveletek már függetlenek attól, hogy a fájl szöveges vagy bináris, mivel nem a fájl belsejében végezzük ezeket a műveleteket, hanem magával a fájllal. Ilyenek a létrehozás, törlés, átnevezés, áthelyezés és másolás. Ezekről, és a könyvtárak (mappák) kezeléséről lesz szó ebben a leckében.
Ha az Alapok 14. leckéjében nem olvastad el a rekurzió című részt, akkor most ajánlatos megtenni, mert szükség lesz rá!

Fájl létrehozása

Fájlt létrehozni az előző leckében megismert fopen() függvénnyel tudunk, függetlenül attól, hogy szöveges vagy bináris fájlról van-e szó. Ehhez írási vagy hozzáfűzési módban kell meghívni a függvényt:

	$file = fopen("data/file.doc", "w");

Ekkor a data könyvtárban létrejön a file.doc fájl. A megnyitási módok közti különbségről már volt szó az előző leckében. Létrehozás után mindjárt írhatunk is a fájlba az fwrite()-tal, mivel a fopen() hívása után meg van nyitva a fájl.

Fájl törlése

Fájlt törölni az unlink() függvénnyel tudunk. Mi sem egyszerűbb. Beadjuk paraméterként a fájl elérési útját, és máris megszabadultunk tőle:

	unlink("data/file.doc");

A visszatérési érték true ha sikerült a törlés, false ha nem. Utóbbi esetben megkapjuk a kedvenc warning-gal kezdődő feliratunkat is, ezért ezt a függvényt a @ operátorral együtt érdemes használni.

Fájl áthelyezése és átnevezése

Egy fájl áthelyezése és átnevezése tulajdonképpen ugyanannak az általános műveletnek két speciális formája. Mindkét műveletet a rename() függvénnyel tudjuk végrehajtani. Ezzel a függvénnyel egy fájl teljes elérési útját tudjuk módosítani. Például a fenti fájl elérési útja: data/file.doc Ez azt jelenti, hogy a fájl a data könyvtárban van, és a neve file.doc. Az áthelyezés a fájl helyét módosítja, az átnevezés pedig a fájl nevét. Mivel a rename() függvénnyel magát az elérési utat tudjuk módosítani, így a segítségével egyszerre mindkét műveletet elvégezhetjük a fájllal:

	rename("data/file.doc", "limlom/egyeb/vacak.txt");

Az első paraméter a forrásfájl (a fájl jelenlegi elérési útja), a második pedig a cálfájl (ahova át akarjuk helyezni). Itt az történt, hogy a fájlt egyrészt áthelyeztük a limlom/egyeb könyvtárba, a neve pedig vacak.txt lett. Amint látható, a kiterjesztést is átírhatjuk, ez a PHP számára ugyanis nem jelent semmi különöset. A visszatérési érték az előzőhöz hasonlóan logikai érték attól függően, hogy sikerült-e a művelet.
Nem túl szerencsés dolog az, ha a célfájl már létezik, vagyis már van egy limlom/egyeb/vacak.txt elérési úttal rendelkező fájlunk, és ezt adjuk meg második paraméterként. Ekkor a rename() vagy felülírja a célfájlt, vagy nem csinál semmit, ez főleg az operációs rendszertől függ, ami alatt fut. Így ha biztosra akarunk menni, ellenőrizzük le áthelyezés/átnevezés előtt a célfájlt a file_exists() függvénnyel. Ha felül szeretnénk írni, akkor előbb töröljük az eredetit az unlink()-kel, és utána indítsuk el az áthelyezést!
További probléma, hogy ez a függvény nem tud könyvtárat létrehozni, így a fenti példában a limlom/egyeb könyvtárnak már léteznie kell, különben nem sokminden fog történni. Egy könyvtár létezését ugyanúgy a file_exists() függvénnyel tudjuk ellenőrizni.
Ezek alapján egy valamivel jobb példa a használatára:

	$targetdir = "limlom/egyeb";
	$targetname = "vacak.txt";
	$file = $targetdir."/".$targetname;
	if (file_exists($file)){
		unlink($file);
	}
	if (file_exists($targetdir)){
		rename("data/file.doc", $file);
	}

Ez azt csinálja, hogy ha már létezik a fájl, akkor törli, és csak akkor végzi el az áthelyezést, ha a célkönyvtár már létezik. A legjobb az lenne persze, ha létrehozná a könyvtárat, ha nem létezik, de azt még nem tudjuk megtenni, egy kicsit később.

Fájl másolása

A másolási művelet annyiban különbözik az áthelyezéstől, hogy az eredei helyen is megmarad a fájl. Meg persze más a függvény neve. Ezen kívül teljesen ugyanaz a helyzet:

	copy("data/file.doc", "limlom/egyeb/vacak.txt");

A paraméterek is teljesen ugyanúgy viselkednek. A függvény lemásolja a data könyvtárban lévő file.doc nevű fájlt, és a másolatot berakja a limlom/egyeb könyvtárba vacak.txt néven. A függvény képességei is megegyeznek a rename() függvénnyel, vagyis könyvtárat nem tud létrehozni, és már létező célfájl itt is bezavarhat, ezért hasonló vizsgálatokat érdemes elvégezni a használat előtt, mint ami fent látható, hacsak nem vagyunk biztosak abban, hogy erre nincs szükség.

Könyvtárak kezelése

Aki esetleg úgy gondolja, hogy az egész állománykezelés ennyiből áll, nevezetesen: "ja, hát csak meg kell hívni egy függvényt, és az mindent megcsinál helyettem, és készen is vagyok", azt el kell szomorítanom, ugyanis van ennek egy bonyolultabb része is, mikor már könyvtárakat is akarunk kezelni.
Azt gondolom mindenki tudja, mik azok a könyvtárak (windowsos elnevezéssel mappák), meg mire valók, egy kevésbé közismert dolgot azonban meg kell említeni. Egy könyvtár ugyebár fájlokat és más könyvtárakat tartalmazhat, amiknek nagyjából tetszőleges lehet a nevük (néhány speciális karakter nem használható), azonban van két különleges állomány minden könyvtárban (egy üres könyvtárban is), a "." (egy pont karakter) és a ".." (két pont karakter). A tallózó programok ezeket általában nem mutatják. Ezek nem fájlok és nem is könyvtárak, hanem könyvtárakra mutató hivatkozások (a Windows alatti parancsikonokhoz hasonlóak). A "." állomány az őt tartalmazó könyvtárra hivatkozik, a ".." pedig a könyvtár szülő könyvtárára, vagyis arra, ami a könyvtárfában közvetlen felette van. Utóbbi ismerős lehet, mivel a HTML-ben is így tudjuk elérni a szülő könyvtárakban lévő állományokat, pl:

	<img alt="" src="../kepek/kep.jpg" />
	<a href="../../index.html" />Kezdőlap</a>

Ha a fenti példa mondjuk az aloldalak/egyebek/kepnezegeto.html elérési úttal rendelkező html fájlban van, akkor az img teg az aloldalak/kepek/kep.jpg képet fogja megjeleníteni, a link pedig a gyökérkönyvtárban lévő index.html fájlra mutat.
De ha az img teg így nézne ki:

	<img alt="" src="./kepek/kep.jpg" />

akkor az az aktuális könyvtárban lévő kepek könyvtárban keresi a képet, vagyis az aloldalak/egyebek/kepek/kep.jpg képet fogja megjeleníteni. Alapértelmezés szerint, ha egy elérési út nem / jellel kezdődik és nem is valamilyen kettőspontot tartalmazó hivatkozással (pl. "c:/", "http://"), akkor az aktuális könyvtárból kell kiindulni, vagyis az elérési út egy relatív elérési út. Ezért nem szükséges megadni az elején a "." hivatkozást. Lehetséges elérési utak:

	kepek/kep.jpg
	./kepek/kep.jpg
	c:/wamp/www/phptanfolyam/kepek/kep.jpg
	/var/www/phptanfolyam/kepek/kep.jpg
	http://php.sikerweb.hu/kepek/kep.jpg

Ezek lehetnek ugyanarra a képre mutató elérési utak, ha feltesszük, hogy a gyökérben lévő index.html-ben vagyunk. Az első kettő relatív elérési út az index.html-hez képest, a 3. és 4. sorok abszolút elérési utak a szerver gyökérkönyvtárához képest, annyi a különbség, hogy a 3. egy Windows operációs rendszer alatti elérési út, a 4.-hez hasonlóval pedig Linux alatt találkozhatunk (ott nincsenek meghajtó-betűjelek). Az 5. pedig szintén egy abszolút hivatkozás a domain neven keresztül (URL).
Ezek az elérési utak egyenértékűek, feltéve ha azok az abszolút elérési utak tényleg helyesek. Ez azt jelenti, hogy egy img teg src attribútumába, vagy egy link href attribútumába, vagy egy include() függvény paraméterébe, vagy akárhova ahol a HTML vagy a PHP kódban egy állományra hivatkozunk, bármelyik formát beírhatjuk. Általában a relatív elérési utat szokás használni, mert így könnyebben áthelyezhető a teljes weboldal egy másik helyre. Például ha mindenhol a 3. formát használjuk, aztán feltöltjük a netre, ahol a szerveren Linux fut, akkor elég kicsi a valószínűsége annak, hogy rendesen fog működni a weboldalunk.
Még egy fontos dolgot érdemes megjegyezni az elérési utakkal kapcsolatban. Ha relatív elérési utakat használunk egy html vagy php fájlban, akkor általában az adott fájlhoz képest kell megadni az elérési utat. Ez alól kivétel az az eset, amikor nem közvetlenül az adott fájl fut a böngészőben, hanem include() függvénnyel van valamelyik másik fájlba behúzva. Úgy érdemes megjegyezni a szabályt, hogy az elérési utakat mindig a böngészőben futó fájlhoz képest kell megadni!

Könyvtár beolvasása

Visszatérve a könyvtárakhoz, nagyjából ugyanazokat a műveleteket lehet elvégezni velük, mint a fájlokkal. Vagyis létrehozás, törlés, áthelyezés/átnevezés és másolás. Ezenkívül a könyvtár tartalmát is szeretnénk beolvasni, vagyis megtudni, hogy milyen fájlok és könyvtárak vannak benne. Először nézzük meg, hogy ezt hogy tudjuk megtenni!
Egy könyvtár beolvasása valamelyest hasonlít egy szöveges fájl beolvasásához. Itt is meg kell nyitni a könyvtárat, ezután olvashatunk belőle, majd a végén be kell zárni. Ez az alábbi módon néz ki:

	$dir = opendir("images/logos");
	// olvasás
	closedir($dir);

Itt nincsenek megnyitási módok, mivel "íráshoz" nem kell megnyitnunk a könyvtárat. Az opendir() függvénnyel tudunk könyvtárat megnyitni, az elérési útját kell neki átadni, és visszaadja az állományleírót, amely a megnyitott könyvtárra hivatkozik. Olvasás után be kell zárni a könyvtárat a closedir() függvénnyel, ami paraméterként az állományleírót várja. Itt is szükség lehet arra, hogy a megnyitás előtt ellenőrizzük, hogy létezik-e a könyvtár, mivel ha egy nem létező könyvtárra vagy egy fájlra engedjük rá az opendir() függvényt, akkor a már megszokott módon warningokban gyönyörködhetünk. Az állomány létezését a file_exists()-tel ellenőrizhetjük, az, hogy az állomány könyvtár-e az is_dir() függvény segítségével dönthető el. Paramétere az állomány elérési útja, és true értéket ad vissza, ha az egy létező könyvtár. Mivel a létezését is ellenőrzi, elegendő csak ezt a függvényt használni:

	$path = "images/logos";
	if (is_dir($path)){
		$dir = opendir($path);
		// olvasás
		closedir($dir);
	}

Hogy egy állomány fájl-e vagy könyvtár, nem dönthető el az alapján, hogy van-e a végén kiterjesztés. Például a valami.txt lehet egy könyvtár neve is, és nem minden fájl végén van feltétlenül kiterjesztés.
Az olvasást nem tudjuk egyetlen művelettel elintézni, egyszerre csak egy állományt tudunk beolvasni a könyvtárból. Ez úgy működik, hogy létrejön egy állománymutató, ami a könyvtár valamelyik állományára mutat, ennek az állománynak a nevét a readdir() függvénnyel kapjuk meg, ami meghíváskor lépteti az állománymutatót. Ha mindegyik állományon végigment, false értéket ad vissza. Így egy ciklussal tudunk végigmenni a könyvtár összes állományán:

	$dir = opendir("images/logos");
	while (($name = readdir($dir)) !== false){
		print $name."; ";
	}
	closedir($dir);

A readdir() függvénynek paraméterként az állományleírót kell átadni, és visszatér annak az állománynak a nevével, amire az állománymutató mutat. Mivel az állománymutatót automatikusan lépteti, a következő hívásnál már a következő állomány nevével tér vissza, tehát a ciklus léptetésével nem kell foglalkoznunk. A ciklust akkor állítjuk le, amikor a visszatérési érték false, ilyet akkor ad vissza, ha már nincs több állomány. Az !== operátort kell használni, mivel a != esetén egy "0" nevű állomány beolvasása esetén is leállna a ciklus. A fenti kód egy ehhez hasonló kimenetet ad:
.; ..; 1.jpg; 2.jpg; saves; watermarks;
Látható, hogy a "." és ".." hivatkozásokat is beolvassa a függvény. Mivel egy könyvtárban nem lehet két azonos nevű állomány, a visszaadott név a könyvtár elérési útjával együtt egyértelműen azonosítja az állományt. Ajánlatos a fájl- és könyvtárnevekben kerülni az ékezetes betűk és szóközök használatát, valamint ha lehet inkább használjunk csak kisbetűket. Ezzel sok problémától kímélhetjük meg magunkat.
Ez a kód nem mindig elég. Ha a könyvtár tartalmaz más könyvtárakat, akkor előfordulhat, hogy azokat is be szeretnénk olvasni. A problémát az okozza, hogy azok is tartalmazhatnak könyvtárakat, és általában nem ismerjük a könyvtárfa mélységét. Ilyen hierarchikus szerkezeteket rendszerint rekurzió segítségével szoktak kezelni. Bár minden rekurzió átalakítható ciklussá, ilyen esetekben a ciklusos változatot sokkal nehezebb megírni. Rekurzió esetén meg tulajdonképpen csak annyit kell csinálnunk, hogy egy függvényt készítünk, ami egy könyvtárat be tud olvasni úgy, hogy a belső könyvtárakra meghívja önmagát. Először tehát a beolvasási műveletet függvénybe kell raknunk. Mivel a belső könyvtárakat ugyanúgy nyitni és zárni kell, az egész programot be kell vágni a függvénybe. A belső könyvtárakat az is_dir() vizsgálatával kapjuk meg, de külön ki kell szűrni a "." és ".." állományokat, mivel az is_dir() ezekre is true-t ad vissza:

	function read_dir_tree($path){
		$dir = opendir($path);
		while (($name = readdir($dir)) !== false){
			if ($name != "." && $name != ".." && is_dir($path."/".$name)){
				read_dir_tree($path."/".$name);
			}
			print $path."/".$name."<br />";
		}
		closedir($dir);
	}

Az eredetihez képest annyi a különbség (a rekurzión kívül), hogy a kiírásnál a teljes elérési úttal együtt írja ki a fájl nevét, különben nem lehetne tudni, hogy melyik alkönyvtárból lettek kiolvasva. A függvény paraméterként a könyvtár elérési útját várja, és annyit csinál, hogy a könyvtárat beolvassa, és a belső könyvtárakra meghívja saját magát. Például egy ehhez hasonló kimenetet kaphatunk:
images/logos/.
images/logos/..
images/logos/1.jpg
images/logos/2.jpg
images/logos/saves/.
images/logos/saves/..
images/logos/saves
images/logos/watermarks/.
images/logos/watermarks/..
images/logos/watermarks/file1.png
images/logos/watermarks
Az ellenőrzéseket most az egyszerűség kedvéért kihagytam, de ezt elég csak a külső könyvtárra megcsinálni, a függvény hívása előtt.

Könyvtár létrehozása

Könyvtárakkal ugyanazokat a műveleteket el lehet végezni, mint a fájlokkal, de sajnos nem mind olyan egyszerű, mert erős korlátozások vannak mindegyikben.
Könyvtárat létrehozni az mkdir() függvénnyel lehet az alábbi módon:

	mkdir("images/logos/new");

Ekkor létrejön egy üres new könyvtár az images/logos könyvtárban. Az üres könyvtár azt jelenti, hogy csak a "." és ".." állományokat tartalmazza. Ez azonban csak akkor történik meg, ha az images/logos könyvtár már létezik, teljes könyvtárágat így nem tudunk létrehozni, ahhoz írnunk kell egy ciklust:

	$path = "images/logos/new";
	$dirs = explode("/", $path);
	$dirname = $dirs[0];
	$n = 0;
	while ($n < count($dirs)){
		mkdir($dirname);
		++$n;
		$dirname += "/".$dirs[$n];
	}

Az elérési utat fel kell darabolni a / jelek mentén, majd szépen lépésről lépésre kell felépíteni a könyvtárágat. Úgy kell működnie, hogy először az mkdir("images"), majd az mkdir("images/logos"), végül az mkdir("images/logos/new") fusson le feltéve, ha az adott könyvtár még nem létezik. A ciklust többféle formában is meg lehet írni, ez egy lehetséges változat. Igen ám, de mi van ha a könyvtárág egy része már létezik? Ekkor nem hívhatjuk meg az mkdir()-t! Ráadásul az mkdir() hívások előtt le kéne ellenőrizni, hogy nincs-e esetleg a létrehozandó könyvtár nevével megegyező nevű fájl. Azt ugyanis előbb törölni kell, és csak utána tudjuk létrehozni a könyvtárat:

	$path = "images/logos/new";
	$dirs = explode("/", $path);
	$dirname = $dirs[0];
	$n = 0;
	while ($n < count($dirs)){
		if (is_file($dirname)){
			$success = @unlink($dirname);
			if (!$success) break;
		}
		if (!is_dir($dirname)){
			mkdir($dirname);
		}
		$dirname += "/".$dirs[++$n];
	}

Azt, hogy egy állomány fájl-e, nem túl meglepő módon egy is_file() nevű függvénnyel ellenőrizhetjük, ami true értéket ad vissza, ha a paraméterében megadott állomány egy létező fájl. A törlés nem csak azért lehet sikertelen, mert a törlendő fájl nem létezik, más oka is lehet (ld. Űrlapok 7. lecke), ezért érdemes leellenőrizni hogy sikerült-e, mert ha nem, akkor nincs mit tenni, meg kell szakítani a ciklust. A ciklusmag utolsó két sorát pedig össze lehet vonni a fent látható módon.

Könyvtár törlése

Könyvtár törlésére az rmdir() függvény használható az alábbi módon:

	rmdir("images/logos");

Sajnos itt sem épp rózsás a helyzet, ugyanis ezzel csak üres könyvtárat lehet törölni (vagyis olyat, amiben csak a "." és ".." hivatkozások vannak meg). Teljes könyvtárág törléséhez ki kell törölni a könyvtárból az összes fájlt, majd a belső könyvtárakra meg kell hívni rekurzívan a függvényt, végül törölhetjük a már kiürített könyvtárágat. Ez a működés alapelve, a megvalósítás pedig egy jó kis házi feladat lesz :)

Könyvtár áthelyezése és átnevezése

Itt szerencsénk van, mert a rename() függvény használható könyvtárak áthelyezésére és átnevezésére ugyanúgy, mint fájlok esetén. A könyvtárakat áthelyezés esetén a benne lévő fájlokkal és alkönyvtárakkal együtt helyezi át:

	rename("images/logos", "kepek/nagy_kepek/egyeb");

Értelemszerűen ekkor az fog történni, hogy ha eddig egy fájl elérési útja pl images/logos/logo1.jpg volt, az ezentúl kepek/nagy_kepek/egyeb/logo1.jpg lesz.

Könyvtár másolása

Itt ismét megkapjuk a pofont, mivel erre egyáltalán nincs semmilyen beépített függvény. Még üres könyvtár másolására se. Úgyhogy a másolást úgy kell megcsinálni, hogy létrehozunk egy üres könyvtárat, majd a forráskönyvtárat beolvassuk, és a fájlokat egyenként átmásoljuk a copy() függvénnyel a célkönyvtárba. Az alkönyvtárakra meg rekurzívan hívjuk a függvényt. Egy lehetséges megoldás ellenőrzések nélkül:

	function copy_dir($source, $target){
		mkdir($target);
		$sourcedir = opendir($source);
		while (($name = readdir($sourcedir)) !== false){
			$path = $source."/".$name;
			if ($name == "." || $name == ".."){
				continue;
			}
			else if (is_dir($path)){
				// könyvtár átmásolása
				copy_dir($path, $target."/".$name);
			}
			else{
				// fájl átmásolása
				copy($path, $target."/".$name);
			}
		}
		closedir($sourcedir);
	}

A függvény első paramétere a lemásolandó könyvtár elérési útja, a második pedig a hely, ahova másolni akarjuk. Utóbbinak léteznie kell, hogy a függvény működjön. Annyira nem bonyolult a dolog, csak oda kell figyelni, hogy a readdir() az állomány nevét adja vissza, de nekünk átlalában az elérési útjára van szükség a másoláskor. A cikluson belül a $path változóban van a forrásfájl vagy könyvtár elérési útja. A két hivatkozást átugorjuk, a könyvtár átmásolásához rekurzívan hívjuk a függvényt, a fájl másolásához pedig a copy()-t.

Házi feladat

1.) Tegyük fel, hogy a weboldalunkon azt szeretnénk, hogy mindig véletlenszerűen jelenjen meg egy fejléc az oldal tetején. Csináltunk egy rakás fejlécképet, és mindet beraktuk az images/logos könyvtárba. A fájlok nevei nincsenek szabályhoz kötve, bármilyen lehet (alkönyvtárak nincsenek). Oldjuk meg, hogy az oldal betöltődésekor ezek közül valamelyik kép jelenjen meg véletlenszerűen!
Próbáljuk meg azt is megcsinálni, hogy kétszer egymás után ugyanaz a kép ne jelenhessen meg! Vagyis ha pl frissítem az oldalt (vagy átlépek egy másik menüpontba), akkor is véletlenszerűen válasszon ki egy képet, de ne ugyanazt, amelyiket a legutóbb.

Megoldás

Nos, akkor az a teendő, hogy beolvassuk a könyvtárban lévő fájlokat, és ezek közül véletlenszerűen választunk egyet. A legegyszerűbb, ha beolvassuk őket egy tömbbe:

		$logok = array();
		$dir = opendir("images/logos");
		while (($name = readdir($dir)) !== false){
			if (is_file("images/logos/".$name)){
				$logok[] = $name;
			}
		}
		closedir($dir);
		$logo = $logok[time() % count($logok)];
		print '<img src="images/logos/'.$logo.'" />';

Az is_file() feltételvizsgálat a "." és ".." állományok kiszűrése miatt kell, de persze név alapján is megvizsgálhatjuk.
Ha azt akarjuk, hogy a következő lefutáskor ne ugyanez jelenjen meg, akkor valahol el kell tárolnunk, hogy most melyik jelent meg, majd a következő futáskor onnan beolvasni, és azt kiszűrni. A legkézenfekvőbb, ha eltároljuk egy szöveges fájlban a kiválasztot fájl nevét:

		// tömb feltöltése ...

		$time = time();
		$logo = $logok[$time % count($logok)];
		$filename = "logo.txt";
		// legutóbbi beolvasása a fájlból
		$file = fopen($filename, "r");
		$lastlogo = fread($file, filesize($filename));
		fclose($file);
		// megváltoztatás, ha azonos
		if ($lastlogo == $logo){
			$logo = $logok[($time + 1) % count($logok)];
		}
		// mostani beírása a fájlba
		$file = fopen($filename, "w");
		fwrite($file, $logo);
		fclose($file);
		print '<img src="images/logos/'.$logo.'" />';

A tömb feltöltése ugyanúgy történik, mint az előbb. A lényeg az, hogy ha a beolvasott érték azonos a kiválasztott logóval, akkor az utána lévőt rakjuk be. A time() visszatérési értékét emiatt egy változóba raktam be, mert előfordulhat, hogy a két hívás között megváltozik az értéke.

2.) Írjunk egy függvényt, ami egy teljes könyvtárágat tud törölni! Tesztelésnél csak óvatosan! :O

Megoldás

Igen, óvatosan, mert a törlés nem a lomtárba való áthelyezést jelenti, így nem fogjuk tudni a kukából kihalászni azt, amit mégse kellett volna letörölni. Az alapelv tehát: ki kell törölni a könyvtárból az összes fájlt, majd a belső könyvtárakra meg kell hívni rekurzívan a függvényt, végül törölhetjük a már kiürített könyvtárágat.

		function delete_dir($dirname){
			$dir = opendir($dirname);
			while (($name = readdir($dir)) !== false){
				$path = $dirname."/".$name;
				if ($name == "." || $name == ".."){
					continue;
				}
				else if (is_dir($path)){
					// könyvtár törlése
					delete_dir($path);
				}
				else{
					// fájl törlése
					@unlink($path);
				}
			}
			closedir($dir);
			rmdir($dirname);
		}

Ha megnézzük, ez tulajdonképpen majdnem ugyanolyan, mint a könyvtármásoló függvény, csak másolás helyett töröl.