Tässä tämmönen yksinkertainen asia, mutta suhteellisen monipuolisesti säädettävissä ja muutoksia voi tehä monesta paikkaa (=> suuri koko). Voi olla hyötyä esim. gallerioita yms. rakennellessa.
Filut saa listattua alihakemistoista ja niiden alihakemistoista... ja tälle rimpsulle voi toki laittaa rajottimen, jos tykkää.
Listauksen saa ulos moniulotteisena taulukkona tai sitte vaan taulukkona, jossa ne koko polkunsa kanssa (voi helpottaa esim. toimenpiteiden suorittamista kaikille tiedostoille tai ainaki ite tartten tätä).
Siinä voi laittaa jonkun tiedostopäätteen tai tiedostopäätteitä taulukossa, jotka on sallittuja ja voi valita, katsotaanko niistä isot ja pienet kirjaimet läpi sormien ja näitä tiedostopäätteitä ei oo pakko ees olla siinä listauksessa, hmmm no joskus tuli tarvittua tuommostakin.
Se vielä nytten tarkistaa, että onko hakemistosta jo listattu tiedostot ja ei listaa niitä uudestaan, mutta sen vois melkeimpä laittaa pois jos tarttee ne samat roinat erilailla listattuna esim.
<?php //Tässä tällainen hiukan ylikommentoitu versio Class FileList { //Ominaisuudet: (jos tää ois php5:lle tehty, niin mikään noista ei ois yleinen) var $file_lists = array(); //Taulukko, johon luodaan tiedostolistaustaulukoita alkioinaan hakemisto, josta listaus on luotu var $listed_dirs = array(); //Taulukko, joka paljastaa, mitkä hakemistot on listattu, vois käyttää edellisestä ominaisuudesta array_keys:iä ja siihen in_arraytä, mutta ei nyt jaksanu, mikäs sitä muistia tuhlaillessa var $current_handler = false; //Ihme muuttujanimi nykyisenä käsiteltävälle/listattavalle hakemistolle var $types = false; //Listauksissa sallitut tiedostotyypit. Tämä voi olla pelkkä yksi tyyppi (merkkijono) tai useita tyyppejä (numeraalinen taulukko) tai sitten jos tyypillä ei ole väliä, annetaan olla epätosi. var $case_insensitive = true; //Boolean-tyyppinen härpäkkä, joka kertoo, onko väliä isoilla ja pienillä kirjaimilla, siis jos on tosi, niin tottakai ei ole väliä, loogista? var $main_dir = false; //Valinnaisesti alustusmetodissa asetettava päähakemisto kaikille listauksille var $return_in_subarrays = true; //Jos jossain vaiheessa halutaan, että tiedostot listattaski moniulotteisissa taulukoissa (siis ei lasketa tuota ekaa ominaisuutta siinä vielä taulukoks), nii annetaan tämän olla tosi, muuten tiedostot siis listataan yhdessä taulukossa koko hakemistopolkunsa, siis mikä ylipäänsä on listaushakemistoihi ja listausten päähakemistoihi annettu. var $return_filename_end = true; //Jos ei haluta listauksissa nähdä tiedostoissa niiden tiedostopäätettä, annetaan tämän olla tosi var $subdir_depth = false; //Jos ei haluta listata koko litaniaa alihakemistojen alihakemistoja ja niiden mahdollisia alihakemsitoja jne., niin tällä voidaan rajoittaa tuon listauksen syvyys, 0 vain kyseinen hakemisto jne. Tämän epätosi arvo kertoo, että mitään syvyysrajoitusta ei ole olemassa. /* Alustusmetodi Argumenttien pitkähköistä nimistä voidaan mielestäni päätellä kaikki suhteellisen olennaiset tiedot ainakin ominaisuuksien kommenttien perusteella, mutta annetaan tästäkin vähän osviittaa. Eli ensimmäisenä voidaan niin halutessa asettaa hakemisto, jossa kaikki listaukset tapahtuvat, toisena mahdollinen listauksen syvyyden rajoitus, kolmantena sallitut tyypit ja neljännelle argumentille annetaan arvoksi tosi, mikäli halutaan asettaa viidennellä argumentilla tiedostonimen lopun sisällyttämisen tila. Tämä sama ehdollisuus toteutetaan myös kuudennella paramterillä koskien nyt seitsemättä, jolla asetetaan niin halutessa listaustaulun moniulotteisuuden tila. Suurena yllätyksenä myös kahdeksas argumentti käyttää samaa taktiikkaa kohdentaen asettamishalukkuuden ilmaisunsa nyt siis yhdeksänteen argumenttiin, joka kertoo, halutaanko, että listattavien tiedostojen muodon tulee olla juuri se mikä on määritelty listattavissa tyypeissä, muussa tapauksessa voidaan tämän antaa olla tosi. Kaikki nämä argumentteina annettavat asetukset vaikuttavat kaikkiin luokasta periytetyllä oliolla tehtäviin listauksiin, ellei toisin aseteta. Tämä metodi ei palauta yhtikäs mitään. */ /*inPHP5: public ja funktion nimi __construct (taikka eipä sillä niin väliä, jos ei luokan nimeä vaiha, mutta on se vähä kökkö kylläki) */ function FileList($main_dir = false, $set_subdir_depth = false, $subdir_depth = false, $types = false, $set_return_filename_end = false, $return_filename_end = true, $set_return_in_subarrays = false, $return_in_subarrays = true, $set_case = false, $case_insensitive = true) { $this->main_dir = $main_dir; if($set_subdir_depth) $this->subdir_depth = $subdir_depth; if($set_return_in_subarrays) $this->return_in_subarrays = $return_in_subarrays; if($set_return_filename_end) $this->return_filename_end = $return_filename_end; if($types != false || $types === 0) $this->types = $types; if($set_case) $this->case_insensitive = $case_insensitive; } /* Tiedostolistan luova metodi Enää en ala selittämään alustusmetodin argumenttien tarkoitusperää, mutta poikkeavuutena siihen on, että tämän metodin argumenttien arvot vaikuttavat vain ja ainoastaan siihen listaukseen, jota sillä ollaan tekmässä ja sen ensimmäinen arvo on hakemisto, josta listaus halutaan tehdä, jonka siis pitää sijaita tai pikemminkin, jonka sijainnin tulee olla ilmoitettu mahdollisesti alustusmetodissa asetetusta päähakemistosta katsottuna. Metodi palauttaa hiukan ehkä turhana tietona hakemiston, jonka perusteella listaus on indeksoitu listaustaulukko-ominaisuuteen, eli siis ensimmäisen argumentin :), ihan kun kutsuja ei sitä itse tietäisi, no sen voi toki vaihtaa vaikka itse listauksen tulokseksi jos tykkää. eli (return $this->file_lists[$this->current_handler];) ja jos haluaa joka kerta tehä uuden listauken, ni tuon jos-lauseen ja sen lohkosta kertovat sulut voi poistaa. */ /*inPHP5: public */function make_list($dir = ".", $set_subdir_depth = false, $subdir_depth = false, $types = false, $set_return_filename_end = false, $return_filename_end = true, $set_return_in_subarrays = false, $return_in_subarrays = true, $set_case = false, $case_insensitive = true) { $this->current_handler = $dir; if($this->listed_dirs[$this->current_handler] !== true) { $this->file_lists[$this->current_handler] = $this->ListFiles($dir,(($types != false || $types === 0)?$types:$this->types), $set_case,$case_insensitive, $set_return_filename_end, $return_filename_end, $set_subdir_depth, $subdir_depth, $set_return_in_subarrays, $return_in_subarrays, true); $this->listed_dirs[$this->current_handler] = true; } return $this->current_handler; } /* Tiedostolistan palauttava metodi Tälle metodille voi antaa sen ainoana parametrina tiedostolistauksen alkion avaimen ja sen vastineeksi annetaan tällä tai, mikäli sitä ei ole asetettu, viimeisimmällä avaimella tehty listaus. */ /*inPHP5: public */function get_list($handler = false) { return $this->file_lists[(($handler===false)?$this->current_handler:$handler)]; } /* Listattavien tiedostotyyppien erillisasetinmetodi Tällä metodilla voidaan siis asettaa kaikissa asetuksen jälkeen tehtävissä listauksissa käytettävät hyväksyttävät tietotyypit, eikä tämä metodi palauta mitään. */ /*inPHP5: public */function set_filter($types) { $this->types = $types; } /* Listattavien tiedostotyyppien tekstikoon sormienläpikatsomisen erillisasetinmetodi Tällä metodilla voidaan asettaa kaikissa asetuksen jälkeen tehtävissä listauksissa käytettävä tiedostomuodon sormienläpikatsomisen tila, eikä siltäkään valitettavasti saada sen toiminnasta kertovaa palautetta. */ /*inPHP5: public */function set_case_insensitive($case_insensitive) { $this->case_insensitive = $case_insensitive; } /* Listaustaulukon moniulotteisuuden erillisasetinmetodi Tällä metodilla voidaan asettaa kaikissa asetuksen jälkeen tehtävien listauksien taulukoiden moniulotteisuus, eikä sekään palauta mitään. */ /*inPHP5: public */function set_subdir_listing($return_in_subarrays) { $this->return_in_subarrays = $return_in_subarrays; } /* Listattavien tiedostojen tiedostomuodon sisällyttämisen tilan erillisasetinmetodi Tällä metodilla voidaan asettaa kaikissa asetuksen jälkeen tehtävissä listauksissa käytettävä tiedostopäätteiden mukaanliittämisen tila, mutta sekään ei palauta mitään eikä ketään. */ /*inPHP5: public */function set_return_filename_end($return_end) { $this->return_filename_end = $return_end; } /* Listauksien käsittävien alihakemistojen sisäkkäisen etenemissyvyyden erillisasetinmetodi Tällä metodilla voidaan asettaa kaikissa asetuksen jälkeen tehtävissä listauksissa niissä käytettävä alihakemistojen etenemissyvyys tai sen käytön tila, mutta tämäkään jäsentoiminto ei ole palautusta tukevalla kannalla. */ /*inPHP5: public */function set_listing_depth($depth) { $this->subdir_depth = $depth; } /* Varsinainen tiedostolistaukset tekevä metodi. Metodi käyttää varsin samoja argumentteja kuin sitä kutsuva make_list-metodi, ehkä hiukan lyhemmillä nimillä, mutta lisäten tähän litaniaan omaa toimintaansa helpottamaan viimeisen argumentin, jolla se saa tietoonsa, onko se ensimmäisessä hakemistossa, mistä lsitauta kutsuttiin, jonka avaulla se voi estää tarpeettomien hakemistopolkujen liittämisen osaksi listaamiaan tiedostoja. Sen toiminta on pääpiirteissään aika simppeli. Se avaa hakemiston, joka sille on työpakaksi määritelty ja listaa sen tiedostot karsien päältä heti hakemistoviittaukset "." ja "..". Näistä tiedostoista se asetetun alihakemistoissa etenemistä hidastavien syvyysrajoitusten puitteissa listaa hakemistoiksi todetut kutsumalla itseään ja muussa tapauksessa siis tiedostoiksi todetut tiedostot, joiden tiedostotyyppi on rajoitettujen tyyppien listalla tarkistaen tämän isCorrectFiletype-metodin avulla. Lopuksi metodi sulkee avatun hakemiston ja palauttaa listatut tiedostot ja käytettäessä moniulotteista listausta syvyysrajoituksestolla mahdollisesti myös tyhjiä hakemistoja merkiksi siitä, että kyseinen kohde kuitenkin on hakemisto. Mielestäni tämän olisi luokan muun käyttöliittymäksi määritetyn metodi-rimpsun takia hyvä olla vain luokan sisäiseen käyttöön suunnattu toiminto, mutta lähinnä koska tästä voi olla montaa mieltä, ei tämä vain yleiseen tiedostolistaushelpotukseen tehty luokka hyödynnä PHP5:n uusia ominaisuuksia. */ /*inPHP5: private */function ListFiles($dir = ".", $types = false, $set_case_i = false, $case_i = true, $set_return_filename_end = false, $return_filename_end = true, $set_depth = false, $depth = false, $set_return_in_subarrays = false, $return_in_subarrays = true, $first_time = true) { $files = array(); $depth = ($set_depth)?$depth:$this->subdir_depth; $dh = opendir((($this->main_dir != false)?($this->main_dir."/"):"").((empty($dir))?"":$dir)); while(false !== ($file = readdir($dh))) { if($file != ".." && $file != ".") { if(@is_dir((($this->main_dir != false)?($this->main_dir."/"):"") . ((empty($dir))?"":$dir)."/".$file) && ($depth === false || $depth>0)) { if((($set_return_in_subarrays) ? $return_in_subarrays : $this->return_in_subarrays)) $files[$file] = $this->ListFiles(((!empty($dir))?($dir."/"):"") . $file, $types, $set_case_i, $case_i, $set_return_filename_end, $return_filename_end, $set_depth, (($depth==false)?false:($depth-1)), $set_return_in_subarrays, $return_in_subarrays, false); else $files = array_merge($files, $this->ListFiles($dir."/".$file, $types, $set_case_i, $case_i, $set_return_filename_end, $return_filename_end, $set_depth, (($deep!==false)?($deep-1):false), $set_return_in_subarrays, $return_in_subarrays, false)); } elseif(($end_length = $this->isCorrectFiletype($file, $set_case_i, $case_i, ((($set_return_filename_end ? $return_filename_end : $this->return_filename_end)) ? false : true), $types))) $files[] = (($set_return_in_subarrays) ? $return_in_subarrays : $this->return_in_subarrays) ? (($end_length===true) ? $file:substr($file,0,-($end_length))) : ((($first_time) ? "" : ((!empty($dir)) ? ($dir."/") : "")) . (($end_length===true) ? $file : substr($file, 0, -($end_length)))); } } closedir($dh); return $files; } /* Tiedostotyypin tarkistajametodi Tämänhän olisi voinut tehdä raskaammalla kaavalla tarkistamaan itse tiedoston mimme-tyyppejä, mutta koska ympäristönä on useimmiten oma tai yleinen luotettavaa sisältöä kantava palvelin, luottaa tämä metodi sokeasti, että tiedoston pääte on sama kuin sen tyyppi. Mikäli tämä piirre häiritsee, tarjoaa tämä funktio kätevähkösti muokattavan alustan myös tälle raskaammalle tarkistukselle. Tai mikäli esim. kuvagalleria on kyseessä, niin voisihan tiedostot tarkistaa myös niiden exiff-tietojen perusteella. Mutta hypätäämpä tellukselta kuuhun ja tartutahan argumentteihin. Ensimmmäisenä tämä metodi saa ainoan pakollisen argumenttinsa, tiedostonimen, joka on ainakin metodin nykyisestä toiminnasta johtuen vielä vailla hekmistopolkua. Toinen metodi säätelee tiedostomuodon koon sormienläpikatsomisen tilan asettamista ja seuraava itse tilaa. Neljäs paramteri kertoo, halutaanko metodin palauttavan oikeaksi havaitun tiedostomuodon pituuden ja viimeinen kertoo tiedostotyypit, jotka sallitaan. Aluksi metodi tarksitaa, että mikäli argumentteina annettujen hyväksyttyjen tyyppien arvo on epätosi, niin voidaitaisiin kokeilla yleisesti säädettyjä tyyppejä. Samankaltaista tarkistusta se tekee tiedostokoon piittamista käsittelevän argumentin kohdalla. Mikäli sitten vihdoin käyttöön saatuja tyyppejä on useampia, tehdään niistä jokaisesta itse metodiin viittaavia kutsuja ja niiden palautusarvojen positiivisuuden perusteella jopa jonkun näiden palautusarvojen, jotka siis voivat olla tiedostonimen päätteen pituus tai vain tosi, palautuksen. Mikäli taas osoittautuu, että joko metodin itse itseään kutsuttaessa taulukko ei ole moniulotteinen tai alkuperäisiä tyyppejä on muuten vaan yksi, tarkistetaan ensin, onko sitä asetettu ollenkaan ja mikäli ei, palautetaan tosi, eli että kyllähän tiedosto kelpaa listattavaksi, kun ei kerran ole minkäänlaista filtteröintilistaa. Mikäli ehto ei olekaan epätosi, on se luultavammin merkkijono, eli voidaan siirtyä tarkistamaan, onko käytössä isoja ja pieniä kirjaimia erotteleva lajittelutyyppi, vai ei, ja tämän perusteella tehdä asianmukainen tarkistus siten, että kummassakin tapauksessa tarkistetaan vain tiedostomuodon pituinen osa tiedostonimen lopusta. */ /*inPHP5: private */function isCorrectFiletype($filename, $set_case_i = false, $case_i = true, $return_length = true, $types = false) { if($types === false) $types = $this->types; $case_insensitive = ($set_case_i)?$case_i:$this->case_insensitive; if(is_array($types)) { foreach($types as $type) if(($end_length = $this->isCorrectFiletype($filename,$set_case_i,$case_i,$return_length,$type))) return $end_length; } elseif(is_string($types)) { if($types == false) return true; if(!$case_insensitive) { if(substr($filename,-(($end_length=strlen($types)))) == $types) return ($return_length)?$end_length:true; } elseif(stristr($types,substr($filename,-(($end_length=strlen($types)))))) return ($return_length)?$end_length:true; } else return true; return false; } } ?>
<?php //Tässä versio niille, jotka eivät pidä kommenteistani Class FileList { var $file_lists = array(); var $listed_dirs = array(); var $current_handler = false; var $types = false; var $case_insensitive = true; var $main_dir = false; var $return_in_subarrays = true; var $return_filename_end = true; var $subdir_depth = false; function FileList($main_dir = false, $set_subdir_depth = false, $subdir_depth = false, $types = false, $set_return_filename_end = false, $return_filename_end = true, $set_return_in_subarrays = false, $return_in_subarrays = true, $set_case = false, $case_insensitive = true) { $this->main_dir = $main_dir; if($set_subdir_depth) $this->subdir_depth = $subdir_depth; if($set_return_in_subarrays) $this->return_in_subarrays = $return_in_subarrays; if($set_return_filename_end) $this->return_filename_end = $return_filename_end; if($types != false || $types === 0) $this->types = $types; if($set_case) $this->case_insensitive = $case_insensitive; } function make_list($dir = ".", $set_subdir_depth = false, $subdir_depth = false, $types = false, $set_return_filename_end = false, $return_filename_end = true, $set_return_in_subarrays = false, $return_in_subarrays = true, $set_case = false, $case_insensitive = true) { $this->current_handler = $dir; if($this->listed_dirs[$this->current_handler] !== true) { $this->file_lists[$this->current_handler] = $this->ListFiles($dir, (($types != false || $types === 0) ? $types : $this->types), $set_case, $case_insensitive, $set_return_filename_end, $return_filename_end, $set_subdir_depth, $subdir_depth, $set_return_in_subarrays, $return_in_subarrays, true); $this->listed_dirs[$this->current_handler] = true; } return $this->current_handler; } function get_list($handler = false) { return $this->file_lists[(($handler===false)?$this->current_handler:$handler)]; } function set_filter($types) { $this->types = $types; } function set_case_insensitive($case_insensitive) { $this->case_insensitive = $case_insensitive; } function set_subdir_listing($return_in_subarrays) { $this->return_in_subarrays = $return_in_subarrays; } function set_return_filename_end($return_end) { $this->return_filename_end = $return_end; } function set_listing_depth($depth) { $this->subdir_depth = $depth; } function ListFiles($dir = ".", $types = false, $set_case_i = false, $case_i = true, $set_return_filename_end = false, $return_filename_end = true, $set_depth = false, $depth = false, $set_return_in_subarrays = false, $return_in_subarrays = true, $first_time = true) { $files = array(); $depth = ($set_depth)?$depth:$this->subdir_depth; $dh = opendir((($this->main_dir != false)?($this->main_dir."/"):"").((empty($dir))?"":$dir)); while(false !== ($file = readdir($dh))) { if($file != ".." && $file != ".") { if(@is_dir((($this->main_dir != false)?($this->main_dir."/"):"") . ((empty($dir))?"":$dir)."/".$file) && ($depth === false || $depth>0)) { if((($set_return_in_subarrays) ? $return_in_subarrays : $this->return_in_subarrays)) $files[$file] = $this->ListFiles(((!empty($dir))?($dir."/"):"") . $file, $types, $set_case_i, $case_i, $set_return_filename_end, $return_filename_end, $set_depth, (($depth==false) ? false : ($depth-1)), $set_return_in_subarrays, $return_in_subarrays, false); else $files = array_merge($files, $this->ListFiles($dir."/".$file, $types, $set_case_i, $case_i, $set_return_filename_end, $return_filename_end, $set_depth, (($deep!==false) ? ($deep-1) : false), $set_return_in_subarrays, $return_in_subarrays, false)); } elseif(($end_length = $this->isCorrectFiletype($file, $set_case_i, $case_i, ((($set_return_filename_end ? $return_filename_end : $this->return_filename_end))?false:true), $types))) $files[] = (($set_return_in_subarrays) ? $return_in_subarrays : $this->return_in_subarrays) ? (($end_length===true) ? $file:substr($file,0, -($end_length))) : ((($first_time) ? "" : ((!empty($dir))?($dir."/") : "")) . (($end_length===true) ? $file : substr($file, 0, -($end_length)))); } } closedir($dh); return $files; } function isCorrectFiletype($filename, $set_case_i = false, $case_i = true, $return_length = true, $types = false) { if($types === false) $types = $this->types; $case_insensitive = ($set_case_i) ? $case_i : $this->case_insensitive; if(is_array($types)) { foreach($types as $type) if(($end_length = $this->isCorrectFiletype($filename, $set_case_i, $case_i, $return_length, $type))) return $end_length; } elseif(is_string($types)) { if($types == false) return true; if(!$case_insensitive) { if(substr($filename, -(($end_length=strlen($types)))) == $types) return ($return_length) ? $end_length : true; } elseif(stristr($types,substr($filename, -(($end_length=strlen($types)))))) return ($return_length) ? $end_length : true; } else return true; return false; } } ?>
Kerrankin joku on todellakin kommentoinut koodiansa XD Siitä kiitokset!
Hankalan näköistä. Tosta vois olla esimerkkitestisivu jossain.
Ehkäpä vähän hankalan näköistä, mutta kommentteja ainakin riittävästi.
Hyvät oppaat
Kommentoinnista iso plussa mutta koodi voisi muuten olla huomattavasti selkeämpää. Rivien pituutta voisi rajoittaa ja muutenkin tehdä vähän ilmavampaa. Luettavuus on nyt niin huonoa, että koodin toiminnasta vaikea sanoa mitään.
Kelpo koodi luokkana. En tosin "jaksanut" lukea ajatuksella kaikkea läpi, mutta yksinkertainen tiedostojen listaaminen hakemistosta käy myös näin;
<?php $Hakemisto = $_SERVER['DOCUMENT_ROOT']; if ($handle = opendir($Hakemisto)) { echo "<table align=\"center\" width=\"390\">"; while (false !== ($file = readdir($handle))) { if ($file != "." && $file != ".." && $file != "...") { echo "\n<tr><td class=\"leipis\"> $file</td><td width=\"30\"></td><td width=\"80\"> [<a class=\"leipis\" target=\"new\" href=\$file\"> Lataa</a>]</td></tr>\n"; } } echo "</table>"; closedir($handle); } ?>
MtJ: et ilmeisestikään ole tutustunut koodiin. Tuota tiedostonlistaustapaahan se käyttää, mutta listaa myös alihakemistot ja niiden alihakemistot ja niin edelleen, mutta siis palauttaa tiedostot taulukkona, josta niistä on helppo esim. foreach-silmukalla tehdä kuvailemiasi tulostuslistauksia. Nuo luokan tekemät listaukset kun ovat lähinnä tarkoitettu käytettäväksi koodissa, ei suoranaisesti tulosteena.
Asiallisin kommentti kooodissasi taisi olla "//Tässä tällainen hiukan ylikommentoitu versio" :D
Aihe on jo aika vanha, joten et voi enää vastata siihen.