Miten olisi helppo tapa toteuttaa PHP:lla, niin että etsitään määrätystä hakemistosta annetulla nimellä tiedostoja vaikka ne ovatkin eri muotoisia.
Esimerkki:
Jos on määritetty niin että etsitään tiedostoja, joissa on nimi "kissa", ja löydetään tiedosto kissa.avi. Sitten seuraavaksi on määritetty etsittäväksi koira ja löydetään koira.wmv. Eli tarkoitus on etsitä tiedostoja joissa on määritelty nimi, mutta tiedostopäätteellä ei ole väliä.
kissa.avi
koira.wmv
combo kirjoitti:
Miten olisi helppo tapa toteuttaa PHP:lla, niin että etsitään määrätystä hakemistosta annetulla nimellä tiedostoja vaikka ne ovatkin eri muotoisia.
Metabolix kertoikin jo, miten glob-funktiolla haetaan tiedostoja. Se ei kuitenkaan hae alikansioista, mutta kirjoitin lyhyen funktion, joka toimii rekursiivisesti. Siinä käytetään globaaleja muuttujia, mikä ei ole hyvän ohjelmointitavan mukaista, mutta sillä saavutettaneen pieni nopeusetu.
Edit: Ei enään globaaleja muuttujia ja nyt koodikin toimii kunnolla.
function etsi ($hak, $etsittava, &$tiedostot) { foreach (scandir ($hak) as $i) { if ($i != "." && $i != "..") { if (is_dir ("$hak/$i")) etsi ("$hak/$i", $etsittava, $tiedostot); elseif (fnmatch ($etsittava, $i)) $tiedostot [] = "$hak/$i"; } } } $t = array (); etsi (".", "*.php", $t); echo implode ("\n", $t);
-tossu-, globaalien muuttujien nopeusetu ei varmasti ole merkittävä, jos sellaista on lainkaan, ja lisäksi niistä seuraa merkittävää hämminkiä koodiin, joten kannattaa saman tien tehdä kunnolla. Funktiosi myös toimii väärin: palautetuista nimistä ei selviä, missä hakemistossa tiedostot ovat, ja hakukaan ei etene syvemmille tasoille, koska esim. hakemiston x/y sijaan yrität hakea suoraan hakemistosta y.
Oikeasti rekursiivinen haku toimisi esimerkiksi näin:
function etsi($hak, $etsittava = "*") { if (!is_dir($hak)) { return array(); } $tiedostot = array(); etsi__rek($hak, $etsittava, $tiedostot); return $tiedostot; } function etsi__rek($hak, $etsittava, &$tiedostot) { foreach (scandir($hak) as $nimi) { if ($nimi == "." || $nimi == "..") { continue; } if ($hak == ".") { $kokonimi = $nimi; } else { $kokonimi = "{$hak}/{$nimi}"; } if (is_dir($kokonimi)) { etsi__rek($kokonimi, $etsittava, $tiedostot); } elseif (fnmatch($etsittava, $nimi)) { $tiedostot[] = $kokonimi; } } } $lista = etsi("hakemisto", "*kissa*"); echo htmlspecialchars(implode("\n", $lista). "\n");
Sitä paitsi kysyjä halusi etsiä "määrätystä hakemistosta" eli minun käsittääkseni vain juuri siitä eikä rekursiivisesti sen alta.
Metabolix kirjoitti:
-tossu-, globaalien muuttujien nopeusetu ei varmasti ole merkittävä, jos sellaista on lainkaan, ja lisäksi niistä seuraa merkittävää hämminkiä koodiin, joten kannattaa saman tien tehdä kunnolla. Funktiosi myös toimii väärin
Huomasin itsekin nuo virheet heti kun sanoit niistä. Ei kannata koodata yöllä väsyneenä, tai sitten koodi pitää ainakin testata kunnolla. Onneksi täällä on ihmisiä, jotka huomaavat viat. Taidan mennä nukkumaan ja jatkaa koodausta huomenna, ettei tule lisää samanlaisia idiootti-mokia.
Aihe on jo aika vanha, joten et voi enää vastata siihen.