Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: php ja opendir

Sivun loppuun

katket [22.08.2008 23:04:55]

#

opendirillähän voi listata kansion sisällön.
Eli minulla on seuraavanlainen

 <?php
$nim = opendir('/home/ktunnus/public_html/testi/');
while ($ltied = readdir($nim)) {
    if (is_dir($ltied))
        {

	        echo "$ltied";
}
closedir($nim);
 ?>

Tuon polun tilallahan voisi olla pelkkä piste myös. Nyt tämä listaa sisällön siitä kansiosta missä tiedosto on tällä hetkellä. Mutta onko mahdollista mennä puussa ylös tai alas? Eli jos haluaisin listata vaikka testi/jokumuu kansion sisällön tai public_html/jokumuu kansion.
Toivottavasti joku ymmärtää mitä tarkoitan.

Mod. lisäsi kooditagit

jmp [22.08.2008 23:20:32]

#

Ns. suhteellisen hakemistopolun voi kirjoittaa esim. näin:

.        = nykyinen hakemisto
../      = ylempi hakemisto
../../   = kaksi hakemistoa ylempi hakemisto hakemistopuussa
./testi  = nykyisessä hakemistossa sijaitseva hakemisto (alahakemisto) nimeltä "testi"

tsuriga [22.08.2008 23:26:43]

#

EDIT: Minen varmaankaa tajunnu oikein, joten karsinpa viestistäin alun poies.

Jos kyse oli siitä, että kuinka pääset tuossa silmukassa kohdatessasi hakemiston taas sitä listaamaan, niin teet tuosta funktion, jolle annat parametrina listattavan hakemiston. Esimerkkinä Rekursiivinen hakemistolistaus globia käyttäen. Tuohon kun annat multidimensional-parametriksi TRUE niin saat hakemiston ja sen alihakemistojen tiedostot (ja valinnaisesti myös hakemistot) listattua. Ei tosin ole mikään tehokkain ratkaisu jos listattava hakemisto sisältää paljon alihakemistoja, ellei funktioon lisää limittiä (saatoin joskus moisen version vääntää, mutta en ole sitä koodivinkkiin päivittänyt). Heitän tuossa yön tai huomisen puolella vaihtoehdon iteraattoreilla kunhan keksin semmoisen. LimitIterator + DirectoryIterator.

katket [23.08.2008 18:02:37]

#

Tuo ../ ei toiminut ylös- eikä alaspäin. Jos kirjoittaa polun kokonaan, pääsee alaspäin muttei ylöspäin. Rekursiivi-esimerkkiä en saanut toimimaan.

jmp [23.08.2008 18:22:21]

#

Huomasithan, että koodisi tulostaa vain hakemistojen nimet? (Tämä voi olla tarkoituskin mutta varmistanpahan vain.) Lisäksi ainakin yllä antamastasi koodinpätkästä puuttuu lopusta yksi (while-silmukan) aaltosulku. Lieneekö näillä mitään tekemistä toimimattomuuden kanssa, itselläni nimittäin tuo ../ toimii aivan kuten pitääkin.

katket [24.08.2008 14:35:42]

#

Juu, pelkästään nimet haluankin listata. Koodissani on myös tuo toinen aaltosulku, se jäi näköjään tuosta esimerkistä pois. Eli laitan uudestaan koodin.

<?php
$nim = opendir('.');
while ($ltied = readdir($nim)) {
if (is_dir($ltied))
{
echo "$ltied";
echo "<br>";
}
}
closedir($nim);
?>

Uudestaan kun testailin niin ./alakansio toimii mutta ylöspäin ei pääse. Jos laitan ../ se listaa tässä sijainnissa olevat kansion eli lopputulos on sama kuin pelkkä .
Käytössä php5, onko sillä mitään merkitystä? Tuskin.

jmp [24.08.2008 17:39:02]

#

PHP:n versiolla ei ole merkitystä. Testasin tuon aiemmin väärin, mutta nyt tiedän syyn. Ongelma ei ole nimittäin siinä, etteikö ../:llä pääsisi hakemistopuussa ylöspäin, vaan is_dir()-funktion toteutuksessa. Kyseinen funktio ilmeisesti palauttaa vain tiedoston nimen, eikä sen koko polkua. Funktio yrittää siis etsiä hakemistoa siitä hakemistosta, missä skripti sijaitsee.

Tämä on helposti korjattu tallentamalla hakemisto muuttujaan ja lisäämällä se is_dir()-funktion kutsuun $ltied-muuttujan kaveriksi. Eli koodiasi mukaillen jotakuinkin näin:

<?php
$hakemisto = '../';
$nim = opendir($hakemisto);
while ($ltied = readdir($nim))
{
    if (is_dir($hakemisto . $ltied))
        echo "$ltied<br>";
}
closedir($nim);
?>

tsuriga [24.08.2008 18:55:58]

#

Iteraattorilla

<?php

class DirectoryFilter extends FilterIterator
{

    protected $_dir;

    public function __construct( $dir )
    {
        $it = new DirectoryIterator( $dir );
        parent::__construct( $it );

        $this->_dir = $dir;
    }

    public function accept()
    {
        return is_dir( $this->_dir . $this->current() ) &&
               !$this->current()->isDot();
    }

}

$searchDir = "../";

foreach ( new DirectoryFilter( $searchDir ) as $dir ) {
    echo "{$dir}\n";
}

?>

globilla

<?php

$searchDir = "../";

foreach ( glob( "{$searchDir}*", GLOB_ONLYDIR ) as $dir ) {
    echo basename( $dir ), "\n";
}

?>

Globilla ei tosin mene ainakaan omassa systeemissäni aakkosjärjestykseen. Tätä varten voidaan tehdä oma vertailufunktio, jota sitten käytettään usort-funktiossa järjestämään alkiot.

jmp [24.08.2008 19:07:22]

#

Korjaus edelliseen viestiini: pelkän tiedostonimen palauttaa siis readdir() eikä is_dir() kuten vahingossa kirjoitin.

katket [24.08.2008 21:50:18]

#

Nyt toimii!!!
Suuret kiitokset jmp:lle.
Kiitos myös tsuriga vaikken vielä iteraattoria kokeillutkaan.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta