简体   繁体   中英

PHP recursive directory menu (different approaches)

I'm trying to create a PHP menu which displays the directories and files in each directory in a list, with links to each file in those directories (but not links to the directories themselves). The directories are numerical as years '2013', '2014', etc., and the files in these directories are PDFs.

In essence:

--- 2013 (not linked)

--------------- 01.pdf (linked)

--------------- 02.pdf (linked)

--------------- 03.pdf (linked)

--- 2014 (not linked)

--------------- 04.pdf (linked)

--------------- 05.pdf (linked)

--------------- 06.pdf (linked)

Currently, my code looks like this:

<?php
function read_dir_content($parent_dir, $depth = 0){
    if ($handle = opendir($parent_dir)) 
    {
        while (false !== ($file = readdir($handle)))
        {
            if(in_array($file, array('.', '..'))) continue;
            if( is_dir($parent_dir . "/" . $file) ){
                $str_result .= "<li>" . read_dir_content($parent_dir . "/" . $file, $depth++) . "</li>";
            }
            $str_result .= "<li><a href='prs/{$file}'>{$file}</a></li>";
        }
        closedir($handle);
    }
    $str_result .= "</ul>";
    return $str_result;
}
echo "<ul>".read_dir_content("prs/")."</ul>";
?>

However, this creates a complete mess when processed. (Unfortunately I cannot post an image as I am a new user, but if it's not too taboo, I will provide a sneaky link to it: http://i.stack.imgur.com/gmIFz.png )

My questions/requests for help on:

1. Why is the order reversed alphanumerically, ie why is 2013 at the bottom of the list and 2014 at the top?

2. How can I remove the links for the directories while keeping the links for the PDFs?

3. I'm confused over why there are empty list items at the end of each directory's list and why they are not logically/consistently spaced, ie why are the 01, 02, 03 PDFs not subordinate to the 2013 (see 'in essence' spacing above)?

NB I am new to programming and PHP, so please bear in mind that my obvious mistake/s might be very simple. Sorry in advance if they are.

edit : what would also be a massive bonus would be to get rid of the ".pdf"s on the end of the filenames, but that is probably an entirely different question/matter.

PHP5 has class called RecursiveDirectoryIterator

This code :

  1. Sorts the list as you want (2013 first then 2014)
  2. Does not show the links to the directories
  3. Solves the formatting troubles
  4. BONUS: removes the pdf extension

..

$myLinks = array();
$dirIterator = new RecursiveDirectoryIterator($parent_dir);

//iterates main prs directory
foreach ($dirIterator as $file) {

    // If its a directory, it will iterate it's children (except if it's . or ..)
    if ($file->isDir() && $file->getFilename() != '.' && $file->getFilename() != '..') {
        $dir = new RecursiveDirectoryIterator($file->getRealPath());
        $myLinks[$file->getFilename()] = array();
        foreach ($dir as $subFile) {
            //If it finds a file whose extension is pdf
            if ($subFile->isFile() && $subFile->getExtension() == 'pdf') {
                // Gets its filename and removes extension
                $fname = str_replace('.pdf', '', $subFile->getFilename());
                // adds the file information to an array
                $myLinks[$file->getFilename()][$fname] = "prs/{$file->getFilename()}/{$subFile->getFilename()}";
            }
        }
    }
}

//Sort our array alphabetically (and numerically) and recursively
ksort_recursive($myLinks);

function ksort_recursive(&$array)
{
    if (!is_array($array)) return;
    ksort($array);
    foreach ($array as $k=>$v) {
        ksort_recursive($array[$k]);
    }
}



// now we print our links as a unordered list
print '<ul>';
foreach ($myLinks as $year => $val) {
    print "<li>$year";
    foreach ($val as $name => $link) {
        print "<li><a href='$link'>$name</a></li>";
    }
    print '</li>';
}
print '</ul>';

First off I see this line in there

$str_result .= "</ul>";

but I don't see an opening ul tag. This is probably the source of the crazy looking result.

1) I would use scandir instead of readdir as it would let you set the sort order.

2,3) Get rid of $str_result .= "</ul>"; and try something like this in your inside your while loop to remove the dir links and get the order right: (NOTE: I have not run this)

if( ! in_array($file, array('.', '..')) ) { 
    if( is_dir($parent_dir . "/" . $file) ){
        $str_result .= "<li>{$file}</li>";
        $str_result .= "<ul>";
        $str_result .= "<li>" . read_dir_content($parent_dir . "/" . $file, $depth++) . "</li>";
        $str_result .= "</ul>";
    } else {
        $str_result .= "<li><a href='prs/{$file}'>{$file}</a></li>";
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM