Avatar billede Slettet bruger
12. januar 2011 - 14:11 Der er 7 kommentarer og
1 løsning

Lægge filstruktur i er array

På min hjemmeside vil jeg gerne give mine brugere mulighed for at uploade filer til deres brugermappe.

Derfor er jeg i gang med at programmere et filhåndteringssystem, men jeg er stødt ind i lidt problemer omkring at få listet brugernes filer på den ønskede måde.

Jeg har følgende kode, der henter en filstruktur ind i et array:

<?php
function files_and_directories($directory) {
    $dir_items = array();
    if ($handle = opendir($directory)) {
        while (false !== ($file = readdir($handle))) {
            if ($file != "." && $file != "..") {
                if (is_dir($directory. "/" . $file)) {
                    $dir_items = array_merge($dir_items, files_and_directories($directory. "/" . $file));
                    $file = $directory . "/" . $file;
                    $dir_items[] = preg_replace("/\/\//si", "/", $file);
                } else {
                    $file = $directory . "/" . $file;
                    $dir_items[] = preg_replace("/\/\//si", "/", $file);
                }
            }
        }
        closedir($handle);
    }
    return $dir_items;
}

$userdir = $_SERVER["DOCUMENT_ROOT"]."/user1";
$files = files_and_directories("$userdir");

echo '<ul>';

foreach ($files as $file) {
    $new_file = str_replace($_SERVER["DOCUMENT_ROOT"], "", $file);
    echo '<li>' . $new_file . '</li>';
}

echo '</ul>';
?>


Mit problem er at ovenstående outputter følgende:
/user1/1.txt
/user1/mappe1
/user1/mappe1/2.txt
/user1/mappe1/mappe2
/user1/mappe1/mappe2/3.txt
/user1/mappe1/mappe2/4.txt
/user1/mappe3
/user1/mappe3/5.txt

Jeg vil gerne have mit output således at der er et lille plus ud for hver mappe, og brugeren så kan klikke på plusset for at udvide mappen.

Som udgangspunkt skal brugerens view se sådan her ud (foldet ud):

- /user1
    - mappe1
        - mappe2
          3.txt
          4.txt
      2.txt
    - mappe3
      5.txt
    1.txt


Jeg ved godt hvordan jeg laver delen med at få plus til at folde ud og minus til at folde sammen, men jeg kan ikke gennemskue hvordan jeg får opbygget mit array, således jeg kan udskrive det med den formattering jeg ønsker.

Hvad skal jeg gøre for at nå frem til den formattering jeg ønsker?

Jeg kender ikke antallet af mapper, filer eller dybden af mappestruktuen på forhånd.
Avatar billede intenz Novice
12. januar 2011 - 15:21 #1
I stedet for at bruge array_merge på et dir, ville jeg vælge at lave et multidimensionelt array.

Så i stedet for:

$dir_items = array_merge($dir_items, files_and_directories($directory. "/" . $file));
$file = $directory . "/" . $file;
$dir_items[] = preg_replace("/\/\//si", "/", $file);


gøre:
$dir_items[$file] = files_and_directories($directory. "/" . $file);


På den måde vil dit array får samme struktur som det du vil udskrive. Så lav en resursiv funktion til udskrive arrayet.

Noget i den stil her:

function echoArray($arr) {
  echo '<ul>';
  foreach ($arr as $key => $value) {
    if (is_array($value)) {
      echoArray(arr)
    } else {
      $new_file = str_replace($_SERVER["DOCUMENT_ROOT"], "", $value);
      echo '<li>' . $new_file . '</li>';
    }
  }
  echo '</ul>';
}

echoArray($files);
Avatar billede showsource Seniormester
12. januar 2011 - 21:33 #2
Jeg har noget kode liggende som læser et givent dir igennem for dirs og filer.
Starter med at vise dirs, og ved klik på dir udvides det som i win stifinder.

Hvis det har interesse ?
Avatar billede Slettet bruger
13. januar 2011 - 11:25 #3
intenz...> Super, kigger på det i aften når jeg kommer hjem

showsource...> Det kan sagtens være interessant. Det vil jeg gerne se.
Avatar billede Slettet bruger
13. januar 2011 - 19:18 #4
intenz...> Har prøvet dit forslag, men kan ikke få det til at virke.

Går ud fra at "echoArray(arr)" skulle have været "echoArray($value)" eller ?

Min kode ser sådan her ud:

<?php
function files_and_directories($directory) {
    $dir_items = array();
    if ($handle = opendir($directory)) {
        while (false !== ($file = readdir($handle))) {
            if ($file != "." && $file != "..") {
                if (is_dir($directory. "/" . $file)) {
                    $dir_items[$file] = files_and_directories($directory. "/" . $file);
                } else {
                    $file = $directory . "/" . $file;
                    $dir_items[] = preg_replace("/\/\//si", "/", $file);
                }
            }
        }
        closedir($handle);
    }
    return $dir_items;
}

$userdir = $_SERVER["DOCUMENT_ROOT"]."/admin";
$files = files_and_directories("$userdir");


function echoArray($arr) {
    echo '<ul>';
    foreach ($arr as $key => $value) {
        if (is_array($value)) {
            echoArray($value)
        } else {
            $new_file = str_replace($_SERVER["DOCUMENT_ROOT"], "", $value);
            echo '<li>' . $new_file . '</li>';
        }
    }
    echo '</ul>';
}

echoArray($files)

?>


Som koden er ovenfor er der bare blank skærm.

Hvis jeg fjerner "echoArray($value)" og erstatter den med "echo $value", er outputtet en liste over de filer der ligger i roden af mappen, samt "Array" for hver undermappe.

Det er som om at "echoArray($value)" går i ring på en forkert måde, men det kan jeg ikke selv gennemskue.
Avatar billede intenz Novice
13. januar 2011 - 20:43 #5
Nå, så må jeg have min localhost frem :)
Jeg tror du fik blank skærm pga. et manglende semicolon efter: echoArray($value)

(fejlmeddelelser er ikke slået til).

Udover det virkede din i første forsøg på min, en lidt forbedret kode er her:

<?php
function files_and_directories($directory) {
    $dir_items = array();
    if ($handle = opendir($directory)) {
        while (false !== ($file = readdir($handle))) {
            if ($file != "." && $file != "..") {
                if (is_dir($directory. "/" . $file)) {
                    $dir_items[$file] = files_and_directories($directory. "/" . $file);
                } else {
                    $dir_items[] = preg_replace("/\/\//si", "/", $file);
                }
            }
        }
        closedir($handle);
    }
    return $dir_items;
}

$userdir = $_SERVER["DOCUMENT_ROOT"]."/admin";
$files = files_and_directories($userdir);

function echoArray($fileArray) {
    echo '<ul>';
    foreach ($fileArray as $dir => $file) {
        if (is_array($file)) {
            echo '<li>' . $dir . '</li>';
            echoArray($file);
        } else {
            echo '<li>' . $file . '</li>';
        }
    }
    echo '</ul>';
}

echoArray($files);
?>
Avatar billede showsource Seniormester
14. januar 2011 - 08:37 #6
Koden som jeg engang fik rodet sammen.

Kan godt gøres mere "stifinder" agtigt.
Og det er jo så i
DEFINE("START_DIR", "/");
at brugernavn skal indgå.

<?php

// CONFIG START _____________________________________________________

// array med dir og filer som evt. ikke skal vises
// "dir" er dir
// "file" er filer

$dont_show = array(
            "dir" => array("phpmyadmin", "hemmeligt_dir"),
            "file" => array(".htaccess", ".ht_pass")
                  );


// Harddisk-sti til roden af domain. IKKE en url og IKKE til dir som skal læses igennem
// Ved at bruge FULD HARDDISK-STI kan scriptet ligge i hvilket som helst underdir til domain
DEFINE("START_PATH", $_SERVER["DOCUMENT_ROOT"]);

// dir som skal læses igennem.
// Eksempler:
// "/" Læser fra rod af domain
// "/fildir", læser "fildir" igennem;
// "/fildir/subdir", læser "subdir" igennem;
DEFINE("START_DIR", "/");

// htmlkoden til billede af en mappe.
// Bruges ved hvert dir.
DEFINE("DIR_IMAGE", "<img src=\"/images/mappe.gif\" align=\"top\" border=\"0\">");

// Hvor meget indrykning pr. subdir der skal være?
DEFINE("INDRYKNING", 24);

// Target på link til filer
// _BLANK åbner et nyt vindue.
// Kan jo også være navnet på en frame/iframe
// Er den tom, bruges der ingen target i link
DEFINE("LINKTARGET", "_BLANK");

// Evt. class i link
// Bruges hvis den ikke er tom
DEFINE("LINKCLASS", "");

// De første tegn brugt til navn på div for hvert dir
// Ved load af siden, løbes doc igennem for div attributer ved hjælp af javascript
// Og starter et divnavn med DIR_NAME_START tjekkes om style skal være hidden eller visible
// Første tegn må IKKE være et tal !!!!!
DEFINE("DIR_NAME_START", "dir_");

// CONFIG END _______________________________________________________


//Tak til detox, www.eksperten.dk/spm/599757, for hjælp med lidt opendir()

function visFiler($dir) {

global $dont_show;

$out = array();

    $d = dir($dir);
    while (false !== ($file = $d->read())) {
        if (is_file($dir."/".$file) && !in_array($file, $dont_show["file"])) {
            $out[] = $file;
        }     
    }

    $d->close();

return $out;

}

function visMapper($dir, &$out) {

global $dont_show, $basepath;

    $d = dir($dir);
    $i = 0;
    while (false !== ($file = $d->read())) {
        if ($file != '.' && $file != '..' && !in_array($file, $dont_show["dir"])) {
            if (is_dir($dir."/".$file)) {
                $out[] = $dir."/".$file;
                visMapper($dir."/".$file, $out);
            $i++;
            }     
        }
    }
    $d->close();
}

function vis_link($link,$text) {

    $url = "\t\t<a href=\"".$link."\"";
    $url .= (LINKTARGET != "" ? " target=\"".LINKTARGET."\"" : "");
    $url .= (LINKCLASS != "" ? " class=\"".LINKCLASS."\"" : "");
    $url .= ">".$text."</a><br />\r\n";

return $url;

}


$basepath = preg_replace("/\/+/", "/", START_PATH);
$basepath = (substr($basepath, -1) == "/" ? substr($basepath, 0, -1) : $basepath);

$basedir = preg_replace("/\/+/", "/", START_DIR);
$basedir = (substr($basedir, -1) == "/" ? substr($basedir, 0, -1) : $basedir);
$basedir = (substr($basedir, 0, 1) != "/" ? "/".$basedir : $basedir);

$mappe = $basepath.$basedir;

// Tjekker om dir findes
if(!is_dir($mappe)) {
echo"Dir som skal l&aelig;ses igennem findes IKKE !!!!! ".$mappe;
exit;
}

// Tjekker om dir kan læses
if(!is_readable($mappe)) {
echo"Der er ikke l&aelig;se rettigheder til \$mappe !!!!! ".$mappe;
exit;
}


// Tjekker DIR_NAME_START er udfyldt
if(trim(DIR_NAME_START) == "") {
echo"DIR_NAME_START kan IKKE v&aelig;re tom!";
exit;
}


// Tjekker første tegn i DIR_NAME_START ikke er et tal ( javascript vil i givet fald fejle )
if(is_numeric(substr(trim(DIR_NAME_START), 0, 1))) {
echo"F&oslash;rste tegn i DIR_NAME_START m&aring; ikke v&aelig;re et tal!";
exit;
}

?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><title>Stifinder script</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />

<script type="text/javascript">

<!-- get_id(), box_click() found at exp.dk -->

function get_id ($id) {

    if (document.all && document.getElementById) {
    return document.all($id);
    } else if (!document.all && document.getElementById) {
    return document.getElementById($id);
    } else {
    return false;
    }
}

function box_click ($id) {

    if (($bcontent = get_id($id))) {
    $bcontent = $bcontent.style;
    } else {
    return false;
    }

    if ($bcontent.visibility == 'hidden') {
    $bcontent.display = 'block';
    $bcontent.visibility = 'visible';
    createCookie($id,$id,5);
    } else {
    $bcontent.display = 'none';
    $bcontent.visibility = 'hidden';
    eraseCookie($id);
    }

}

<!-- http://www.eksperten.dk/spm/743420 -->

function eraseCookie(name) {
    createCookie(name,"",-1);
}

function createCookie(name,value,days) {
    if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
    }else{
    var expires = "";
    }
    document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(cookname) {

    var nameEQ = cookname+ "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}


window.onload = function() {

<!-- http://www.eksperten.dk/spm/769446 -->

var elms = document.getElementsByTagName("div");
var namestart = '<?php echo trim(DIR_NAME_START); ?>';
var nameantal = namestart.length;

    for(i=0,im=elms.length;im>i;i++){

        if(elms[i].id.substr(0,nameantal) == namestart) {

            if(divid = readCookie(elms[i].id)) {

                if (divref = get_id(divid)) {
                divref.style.visibility = 'visible';
                divref.style.display = 'block';
                }

            }

        }

    }

}

</script>

<style type="text/css">

body {
    margin: 0px;
    padding: 48px;
    font-family: verdana;
    font-size: 0.8em;
    color: #000000;
    background-color: #FFFFFF;
    }

a:link {
    color:#002424;
      }
a:visited {
    color:#002424;
          }
a:hover {
    text-decoration:none;
        }

</style>

</head>
<body>

        <noscript><div>Aktiver Javascript i din browser!</div></noscript>

<?php

$liste = array($mappe);

visMapper($mappe, $liste);

    for ($d = 0; $d < count($liste); $d++) {

    $visdir = str_replace($basepath."/", "", $liste[$d]);
    $visdir = (substr($visdir, 0, 1) != "/" ? "/".$visdir : $visdir);
    $dirlink = (strlen($visdir) > 1 ? $visdir."/" : $visdir);


    $dirantal = explode("/", $visdir);
    $t = (count($dirantal)*INDRYKNING);

    $filer = visFiler($basepath.$visdir);
    $antal = count($filer);

    $filestyle = "margin-left: ".INDRYKNING."px; visibility: hidden; display: none;";
    $click = " onclick=\"box_click('".DIR_NAME_START.$d."');\" onmouseover=\"this.style.cursor='pointer';\"";

    echo "\r\n\t<div style=\"margin-left: ".$t."px; padding: 4px;\">\r\n";
    echo "\t<span".$click.">".DIR_IMAGE." <span style=\"font-weight: bold;\">".$visdir."</span> <span style=\"font-size: 0.8em;\">( ".$antal." )</span></span>\r\n";

    echo "\t\t<div id=\"".DIR_NAME_START.$d."\" style=\"".$filestyle."\">\r\n";

        if ($antal > 0) {

        sort($filer);

            for ($i = 0; $i < $antal; $i++) {

            echo vis_link($dirlink.$filer[$i],$filer[$i]);

            }

        }else{

        echo"\t\tIngen filer\r\n";

        }

    echo"\t\t</div>\r\n";

    echo"\t</div>\r\n";

    }

clearstatcache();
?>


</body></html>
Avatar billede Slettet bruger
16. januar 2011 - 19:48 #7
intenz...> Super, det virker som ønsket.
Pointene er hermed dine.

Showsource...> Læg et svar og jeg kaster yderligere 30 point i din retning.
Avatar billede showsource Seniormester
17. januar 2011 - 08:06 #8
Jeg hopper over her
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester