Visualizzazione risultati 1 fino 8 di 8

Discussione: Navigazione tra file e cartelle, problema percorso

  1. #1
    Guest

    Predefinito Navigazione tra file e cartelle, problema percorso

    Salve a tutti, devo fare un esercizio, una specie di file manager semplificato, tuttavia mi sono bloccato abbastanza presto. Il codice che ho scritto sembra funzionare, in pratica ho una cartella di partenza (dalla quale in teoria non si potrebbe risalire, ma questo lo devo ancora implementare), e viene visualizzato il contenuto di quella cartella, se è un file viene scritto in maniera testuale, se è una cartella la faccio diventare un link. Se viene clikkato il link , viene visualizzato il contenuto di quella cartella, compresi i due punti "..", che permettono di risalire di livello. Ora, finchè mi addentro nelle cartelle tutto bene, il problema è quando risalgo di livello, a lungo andare mi ritrovo un percorso del tipo "Contenuti/Dir1/dir2/../../Dir1/../Dir1/../..", che non è molto bello, anche se sembra che venga interpretato correttamente. Ho provato ad usare la funzione realpath(), ma sembra peggiorare la situazione.
    Il codice è questo:

    Codice PHP:
    <?php

    define
    ("ROOT","Contenuti");

    function
    listadir($dir=ROOT){

    $h=opendir($dir);

    while((
    $f=readdir($h))!==FALSE)
    {
    //se è una directory, la trasformo in link clickabile
    if(is_dir("{$dir}/{$f}")&&($f!='.')){
    $percorso="{$dir}/{$f}";
    echo
    "<a href=\"{$_SERVER['PHP_SELF']}?dir1={$percorso}\">{$f}</a><BR>";
    }
    elseif(
    $f!='.' && $f!='..')
    //se è un file, lo stampo come testo
    echo "{$f}<BR>";
    }
    closedir($h);
    }


    ?>

    <HTML>

    <HEAD>
    <TITLE>FILE MANAGER</TITLE>
    </HEAD>

    <BODY>

    <table border="1">
    <tr>
    <td>
    <?php

    if(isset($_GET['dir1'])&&$_GET['dir1']!='')
    listadir($_GET['dir1']);
    else
    listadir();

    ?>
    </td>

    </tr>

    </table>

    </BODY>

    </HTML>
    Qualcuno sa come posso risolvere la questione del path? Qualche suggerimento su come procedere? Devo implementare ancora un po' di cose, e sono già bloccato :P
    Ultima modifica di dreadnaut : 16-02-2013 alle ore 16.09.42 Motivo: + tag [php] per il codice

  2. #2
    L'avatar di dreadnaut
    dreadnaut non è connesso Super Moderatore
    Data registrazione
    22-02-2004
    Messaggi
    6,306

    Predefinito

    Tratta ".." come un caso speciale nel ciclo, ed invece di un link a {$dir}/{$f} mettine uno alla directory superiore —se non sei già alla radice.

    Per prendere la directory superiore, puoi tagliare la stringa —oppure qualcosa tipo dirname(rtrim($dir, '/')).
    Ultima modifica di dreadnaut : 16-02-2013 alle ore 16.13.35

  3. #3
    Guest

    Predefinito

    Ok, però non so bene come agire. Per esempio se io sono arrivato alla Directory1, e voglio risalire di livello, {$dir} contiene "Contenuti/Directory1" e {$f} contiene ".." . Posso anche trattarlo come un caso particolare nel ciclo, ma non so bene come ottenere la directory superiore. Nel senso, potrei trovarmi anche un percorso lungo tipo "Contenuti/Directory1/Directory2/Directory3", come faccio a dirgli che il percorso della cartella superiore è ""Contenuti/Directory1/Directory2/" ? Stavo pensando ad un explode sullo "/", prendere tutti gli elementi dell'array tranne l'ultimo (che dovrebbe essere la cartella corrente), e ricreare la stringa rimettendo gli "/". Ha senso? Non c'è una soluzione più pulita?Non so se è chiaro il discorso :p

  4. #4
    L'avatar di dreadnaut
    dreadnaut non è connesso Super Moderatore
    Data registrazione
    22-02-2004
    Messaggi
    6,306

    Predefinito

    Era già scritto nel mio post precedente

  5. #5
    Guest

    Predefinito

    Ah non avevo letto tutto o_o
    Ora provo, grazie!

  6. #6
    Guest

    Predefinito

    Ok, scusa se ti stresso ancora, ho seguito i tuoi consigli e ho modificato il codice. Ho messo però solo $percorso=dirname($dir); e sembra funzionare, il fatto è che non capisco il perchè funzioni o.o Nel senso, se $dir è "contenuti/dir1/dir2", e poi faccio $percorso=dirname($dir); mi restituisce "contenuti/dir1". Ora, è proprio quello che volevo, ma da quello che ho capito, la funzione dirname() non dovrebbe restituirmi tutto il percorso "contenuti/dir1/dir2", visto che non ho messo nemmeno il rtrim() all'interno, come da te suggerito? Oppure non mi è chiara la funzione dirname()... cioè, capisco se gli passo un percorso del tipo "contenuti/dir1/file.txt, e allora dovrebbe restituirmi solo "contenuti/dir1/", ma se gli passo un percorso di sole cartelle, com'è che mi restituisce la penultima del percorso?

    Questo è il codice modificato
    Codice PHP:
    <?php

    define
    ("ROOT","Contenuti");

    function
    listadir($dir=ROOT){

    $h=opendir($dir);

    while((
    $f=readdir($h))!==FALSE)
    {
    //se è una directory, la trasformo in link clickabile
    if(is_dir("{$dir}/{$f}")&&($f!='.')){
    //se è la directory superiore ".."
    if($f=='..'){
    $percorso=dirname($dir);
    echo
    $percorso."<br>";
    echo
    "<a href=\"{$_SERVER['PHP_SELF']}?dir1={$percorso}\">{$f}</a><BR>";
    }
    //altrimenti è una directory qualsiasi
    else{
    $percorso="{$dir}/{$f}";
    echo
    "<a href=\"{$_SERVER['PHP_SELF']}?dir1={$percorso}\">{$f}</a><BR>";
    }
    }
    //fine if is_dir
    elseif($f!='.' && $f!='..')
    //se è un file, lo stampo come testo
    echo "{$f}<BR>";
    }
    closedir($h);
    }

    ?>
    Ho messo il echo $percorso."<br>"; solo per capire quello che effettivamente stava succedendo:P Grazie ancora per la disponibilità!!

    edit:

    Uhm forse ho capito, dirname($percorso) mi restituisce la cartella in cui è contenuto l'ultimo elemento del percorso, senza fare distinzioni tra file e directory. Quindi se ho contenuti/dir1/file o contenuti/dir1/altra_cartella, mi restituisce sempre contenuti/dir1. Spero di aver capito bene o.o'
    Ultima modifica di dreadnaut : 16-02-2013 alle ore 17.56.06 Motivo: + tag [php] per il codice, indentazione

  7. #7
    L'avatar di dreadnaut
    dreadnaut non è connesso Super Moderatore
    Data registrazione
    22-02-2004
    Messaggi
    6,306

    Predefinito

    Esatto —il trim l'avevo inserito per sicurezza, nel caso ci fossero stati '/' in fondo alla stringa e questo avesse creato problemi.

    Fra parentesi, potresti anche sostituire gli slash con la costante DIRECTORY_SEPARATOR, che varia a seconda del sistema operativo.
    Codice PHP:
    $nuovadir = $dir . DIRECTORY_SEPARATOR . $f;

  8. #8
    Guest

    Predefinito

    Ah bene grazie, mi hai chiarito le idee ^^ Riguardo alla costante DIRECTORY_SEPARATOR, lo terrò presente, però è un esercizio a scopo didattico e so già che lo script dovrà girare su windows :P
    Comunque mi servirebbe ancora un aiuto. In pratica quello che ho scritto era la base, ma l'esercizio vuole che ci siano due sezioni. In pratica anzichè avere una cella (come nel caso precedente) in cui si visualizza l'elenco di file e directory, le celle sono due. Entrambe le sezioni, inizialmente visualizzano il contenuto della cartella "Contenuti", però poi si potrà navigare all'interno delle cartelle in maniera separata, nel senso che io nella prima sezione posso muovermi magari in Contenuti/Dir1/Dir2, mentre nella seconda sezione magari decido di fermarmi a Contenuti/Dir1. Metto un'immagine che magari rende meglio l'idea: . Io dovrei poter navigare nelle directory in una sezione, lasciando l'altra inalterata e viceversa.

    Ora, io ho modificato lo script precedente, ma il risultato non è quello sperato, infatti talvolta le sezioni si invertono. Questo lo script:

    Codice:
    <?php
    
    define("ROOT","Contenuti");
    
    function listadir($dir1=ROOT,$dir2=ROOT){
    
    $h=opendir($dir1);
    
    while(($f=readdir($h))!==FALSE)
    {
     //se è una directory, la trasformo in link clickabile
     if(is_dir("{$dir1}/{$f}")&&($f!='.')){
        
        //se è la directory superiore ".." e non siamo nella directory base
    	if(($f=='..') && ($dir1!=ROOT)){
    	  $percorso=dirname($dir1);
    	  echo "<a href=\"{$_SERVER['PHP_SELF']}?dir1={$percorso}&amp;dir2={$dir2}\">{$f}</a><BR>";
    	  }
    	//altrimenti è una directory qualsiasi  
    	elseif($f!='..'){  
          $percorso="{$dir1}/{$f}";
    	  echo "<a href=\"{$_SERVER['PHP_SELF']}?dir1={$percorso}&amp;dir2={$dir2}\">{$f}</a><BR>";
    	  }
     }//fine if is_dir
     elseif($f!='.' && $f!='..')
     //se è un file, lo stampo come testo
        echo "{$f}<BR>"; 
     }
    closedir($h);
    }
    
    
    ?>
    
    <HTML>
    
    <HEAD>
    <TITLE>FILE MANAGER</TITLE>
    </HEAD>
    
    <BODY>
    
    <table border="1">
    <!-- SEZIONE 1 -->
    <tr>
    <td> 
    <?php
    
    if(isset($_GET['dir1'],$_GET['dir2']) && $_GET['dir1']!='' && $_GET['dir2']!='')
    listadir($_GET['dir1'],$_GET['dir2']);
    else
    listadir();
    
    ?>
    </td>
    
    
    <!-- SEZIONE 2 -->
    
    <td> 
    <?php
    
    if(isset($_GET['dir1'],$_GET['dir2']) && $_GET['dir1']!='' && $_GET['dir2']!='')
    listadir($_GET['dir2'],$_GET['dir1']);
    else
    listadir();
    ?>
    </td>
    </tr>
    
    </table>
    
    </BODY>
    Pensavo di poter passare i parametri a listadir() in base alla sezione, infatti ho listadir($_GET['dir1'],$_GET['dir2']); oppure listadir($_GET['dir2'],$_GET['dir1']); a seconda della sezione, ma la logica è evidentemente sbagliata. Se qualcuno, potesse indicarmi la via su come procedere... credo che cmq avrò per forza bisogno di una terza variabile per gestire la cosa.

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •