[PHP] Remote dir uitlezen met recursieve methode

Pagina: 1
Acties:

Onderwerpen


  • Scott
  • Registratie: December 2004
  • Laatst online: 20-09 21:57

Scott

Ik ben, dus ik tweak

Topicstarter
Ik wil een open directory uitlezen, maar die directory staat niet op de server waar het PHP-bestand wordt uitgevoerd. Ik heb een class gemaakt, waarvan één methode zorgt voor het uitlezen van die map. Omdat ook subdirs uitgelezen moeten worden, is die methode recursief gemaakt.

De code:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function readDirByRegex($directory, $sub_dirs = true) {
        
    preg_match_all("#[img]\"(.*?)\"[/img] <a href=\"(.*?)\">(.*?)</a>#im", file_get_contents($directory), $content, PREG_SET_ORDER);
    
    // print_r($content);

    for ($i = 2; $i < count($content); $i++) {
            
        if ($sub_dirs == true && !strchr($content[$i][3], '.')) {
                
            $this->readDirByRegex($directory.$content[$i][3]);
        }
            
        else {
                
            $list_songs[][$directory] = $content[$i][3];
        }
    }
                
    return $list_songs;
}


Wat er fout gaat: hij leest de submappen niet uit. De bestanden in de root (= $directory) staan, worden wel uitgelezen, maar de bestanden in de submappen niet.

De inhoud van $directory.$content[$i][3] heb ik bekeken, die klopt gewoon. De print_r() die nu een comment is, geeft ook de juiste mappen + bestanden aan.

Voor de zekerheid ook nog even de mapstructuur:
code:
1
2
3
4
5
6
7
/opendir
    - dir
        - dirrr
            - blaat.txt
            - text.txt
        - test.txt
    - boe.txt

[ Voor 6% gewijzigd door Scott op 18-08-2005 12:23 ]


  • Cavorka
  • Registratie: April 2003
  • Laatst online: 27-03-2018

Cavorka

Internet Entrepreneur

Is het niet:
PHP:
1
$this->readDirByRegex($directory. "/" . $content[$i][3]) ;


Wel een lekker manier om een open dir in te lezen trouwens... kan je niet met FTP connecten ofzo? Je moet nu telkens voor elke directory een gehele pagina gaan inlezen. :/

Print gewoon in je loop over $content de file, dan zie je in ieder geval of hij de subdirectory uitleest, of dat het na de 1e recursie dus fout gaat.

En je start je loop bij 2, en toch escape je het geval waar de directory met een . begint? Is dat niet dubbelop?

Zoiets:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function readDirByRegex($directory, $sub_dirs = true) {
        
    preg_match_all("#[img]\"(.*?)\"[/img] <a href=\"(.*?)\">(.*?)</a>#im", file_get_contents($directory), $content, PREG_SET_ORDER) ;
    
    $contentCount = count($content) ;

    for ($i = 2; $i < $contentCount ; $i++) {
  
        print "Basedir: " . $directory . " | File: " . $content[$i][3] . "<br />" ;
          
        if ($sub_dirs == true && !strchr($content[$i][3], '.')) {
            $this->readDirByRegex($directory.$content[$i][3]);
        }
        else {
              $list_songs[][$directory] = $content[$i][3];
        }
    }
                
    return $list_songs;
}

[ Voor 61% gewijzigd door Cavorka op 18-08-2005 14:35 ]

the-blueprints.com - The largest free blueprint collection on the internet: 50000+ drawings.


  • Scott
  • Registratie: December 2004
  • Laatst online: 20-09 21:57

Scott

Ik ben, dus ik tweak

Topicstarter
Cavorka schreef op donderdag 18 augustus 2005 @ 14:30:
Is het niet:
PHP:
1
$this->readDirByRegex($directory. "/" . $content[$i][3]) ;
Nee, er wordt bij een map altijd een / achteraan gevoergd. Dat hoeft dus niet :)
Wel een lekker manier om een open dir in te lezen trouwens... kan je niet met FTP connecten ofzo? Je moet nu telkens voor elke directory een gehele pagina gaan inlezen. :/
Nope, dat gaat helaas niet, omdat niet elke PC een FTP server heeft
En je start je loop bij 2, en toch escape je het geval waar de directory met een . begint? Is dat niet dubbelop?
Nee, ik start mn loop inderdaad bij 2 (omdat de eerste 2 array-waardes links zijn die ik niet hoef te hebben), maar strchr() kijkt of er een . in de bestandsnaam voorkomt. Dit is om te kijken of $content[$i][3] een map (zonder punt) of een bestand is. is_dir() werkt niet, omdat het op een remote server gebeurt.
Zoiets:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function readDirByRegex($directory, $sub_dirs = true) {
        
    preg_match_all("#[img]\"(.*?)\"[/img] <a href=\"(.*?)\">(.*?)</a>#im", file_get_contents($directory), $content, PREG_SET_ORDER) ;
    
    $contentCount = count($content) ;

    for ($i = 2; $i < $contentCount ; $i++) {
  
        print "Basedir: " . $directory . " | File: " . $content[$i][3] . "<br />" ;
          
        if ($sub_dirs == true && !strchr($content[$i][3], '.')) {
            $this->readDirByRegex($directory.$content[$i][3]);
        }
        else {
              $list_songs[][$directory] = $content[$i][3];
        }
    }
                
    return $list_songs;
}
Als ik die code uitvoer, krijg ik netjes, zoals hoort, dit:

Basedir: http://xxx.xx.xxx.xxx/opendir/ | File: dir/
Basedir: http://xxx.xx.xxx.xxx/opendir/dir/ | File: dirrr/
Basedir: http://xxx.xx.xxx.xxx/opendir/dir/dirrr/ | File: blaat.txt
Basedir: http://xxx.xx.xxx.xxx/opendir/dir/dirrr/ | File: pwn3d.txt
Basedir: http://xxx.xx.xxx.xxx/opendir/dir/ | File: test.txt
Basedir: http://xxx.xx.xxx.xxx/opendir/ | File: boe.txt

Alle recursies lijken dus goed te gaan, alleen dan heb ik nu geen idee waar het dan wel fout gaat... Die else wordt zelfs 4× uitgevoerd (zoveel bestanden zijn er ook, dus ook dat klopt), ik heb dan echt geen ideewat er wel fout gaat hoor :?

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Zet dit eens in het begin van je functie:
PHP:
1
static $list_songs;

of geef $list_songs mee als (reference) parameter aan de functie, of maak van regel 12 dit:
PHP:
1
$list_songs = array_merge($this->readDirByRegex($directory.$content[$i][3]), $list_songs);


if ( $sub_dirs == true ) kan natuurlijk ook gewoon if ( $sub_dirs ) worden.

[ Voor 14% gewijzigd door Michali op 18-08-2005 18:02 ]

Noushka's Magnificent Dream | Unity


  • Scott
  • Registratie: December 2004
  • Laatst online: 20-09 21:57

Scott

Ik ben, dus ik tweak

Topicstarter
Michali schreef op donderdag 18 augustus 2005 @ 18:00:
Zet dit eens in het begin van je functie:
PHP:
1
static $list_songs;

of geef $list_songs mee als (reference) parameter aan de functie, of maak van regel 12 dit:
PHP:
1
$list_songs = array_merge($this->readDirByRegex($directory.$content[$i][3]), $list_songs);


if ( $sub_dirs == true ) kan natuurlijk ook gewoon if ( $sub_dirs ) worden.
Juist, dat was de oplossing, heel erg bedankt ! Had inderdaad over het hoofd gezien dat als hij in een subdir zat, er een kopie van die variabele werd gemaakt, heb ik nu opgelost dmv de reference zoals jij adviseerde :)

Nu heb ik nogeen klein probleempje. Als ik de functie aanroep, moet ik $list_songs nu ook meegeven. Alleen als ik bij het aanroepen van de functie (in het begin) een lege array geef, krijg ik de foutmelding "Cannot pass parameter 3 by reference". Ook bij een lege string krijg ik dit. Hoe moet ik dan die parameter in het begin doorgeven ? :)

Maar nogmaals bedankt voor je hulp ! :

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Je kunt er in het begin een default waarde gebruiken. Of je laat de return geheel achterwege en geeft bij het aanroepen van de functie een variabel mee waarin wordt geschreven, een output parameter noemen ze dat.

Noushka's Magnificent Dream | Unity


  • Scott
  • Registratie: December 2004
  • Laatst online: 20-09 21:57

Scott

Ik ben, dus ik tweak

Topicstarter
Michali schreef op donderdag 18 augustus 2005 @ 18:47:
Je kunt er in het begin een default waarde gebruiken. Of je laat de return geheel achterwege en geeft bij het aanroepen van de functie een variabel mee waarin wordt geschreven, een output parameter noemen ze dat.
Als ik een default waarde gebruik, krijg ik een foutmelding, dat hij een onverwachte = tegenkomt. Dat lijkt dus niet te kunnen, een default waarde met een reference.

En dat met die output parameter, dat begrijp ik niet Hoe zou dat in mijn code er dan uitzien ? Dit is de vernieuwde code:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function readDirByRegex($directory, $sub_dirs = true, &$list_songs) {
        
    preg_match_all("#[img]\"(.*?)\"[/img] <a href=\"(.*?)\">(.*?)</a>#im", file_get_contents($directory), $content, PREG_SET_ORDER);
    
    $list_songs = array();
    
    for ($i = 2; $i < count($content); $i++) {
        
        if ($sub_dirs == true && !strchr($content[$i][3], '.')) {
            
            $this->readDirByRegex($directory.$content[$i][3], true, $list_songs);
        }
        
        else {
            
            $list_songs[][$directory] = $content[$i][3];
        }
    }
    
    //return $list_songs;
}


Die return gaat dan weg, maar wat komt er dan in de plaats ?

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Waar je de functie aanroept moet je dan een variabel meegeven ipv. het resultaat opvangen mbv. een assignment. Dan krijg je dus iets als dit:
PHP:
1
2
3
4
$songs = array();
$dirUtils->readDirByRegex("songs", true, $songs);
// ipv. 
// $songs = $dirUtils->readDirByRegex("songs");

Beter is trouwens mischien nog om van $sub_dirs de laatste parameter te maken.

Noushka's Magnificent Dream | Unity


  • Scott
  • Registratie: December 2004
  • Laatst online: 20-09 21:57

Scott

Ik ben, dus ik tweak

Topicstarter
Michali schreef op donderdag 18 augustus 2005 @ 18:56:
Waar je de functie aanroept moet je dan een variabel meegeven ipv. het resultaat opvangen mbv. een assignment. Dan krijg je dus iets als dit:
PHP:
1
2
3
4
$songs = array();
$dirUtils->readDirByRegex("songs", true, $songs);
// ipv. 
// $songs = $dirUtils->readDirByRegex("songs");

Beter is trouwens mischien nog om van $sub_dirs de laatste parameter te maken.
Ah, dat voorkomt de foutmelding inderdaad :D Dacht eigenlijk dat dat ook weer die foutmelding op zou leveren, maar had het natuurlijk wel ff moeten proberen. Bedankt voor je hulp ! :)
Pagina: 1