Search code examples
phpgalleryreaddir

PHP - reading folder, all subfolders, and files in subfolders


I have a folder named "inspections" which has a number of subfolders named "location 1", "location 2", "location 3", etc. each with around 10-20 .png images in it.

What I am trying to do, is to read the directories of the "inspections" folder, and then read all the image files in each of the folders before returning them as a gallery on my index.php site. The problem is that I get no error message but the script doesnt return anything. I believe the problem is with generating the $files variable for each subfolder as I deploy the same script for reading folder content on another site.

Perhaps someone can point me in the right direction?

    <?php
$dir = './inspections/';
if ($handle = opendir($dir)) 
{
    $blacklist = array('.', '..', 'default', 'default.php', 'desc.txt');
    while (false !== ($folder = readdir($handle))) 
    {
        if (!in_array($folder, $blacklist)) 
        {
            if (file_exists($dir . $folder . '/desc.txt')) 
                {
                    while (false !== ($file = readdir($handle))) 
                    {
                        if (!in_array($file, $blacklist)) 
                        {
                            $chain = file_get_contents($dir . $folder . '/chain.txt');
                            $website = file_get_contents($dir . $folder . '/website.txt');
                            $location = file_get_contents($dir . $folder . '/location.txt');
                            $desc = file_get_contents($dir . $folder . '/desc.txt', NULL, NULL, 0, 250) . '...';
                            echo "
                                <!-- Post -->
                                <div class=\"post\">
                                  <div class=\"user-block\">
                                    <img class=\"img-circle img-bordered-sm\" src=\"../dist/img/logo/logo_".$chain."\" alt=\"\">
                                        <span class=\"username\">
                                          <a href=\"".$website."\" target=\"_blank\">".$folder."</a>
                                        </span>
                                    <span class=\"description\"><i class=\"fa fa-map-pin\"></i> ".$location." - Posted on ". $date . "</span>
                                  </div>
                                  <!-- /.user-block -->
                                  <p>".$desc."</p>
                                  <div class=\"lightBoxGallery\">
                                  <a href=\"".$dir . $folder . "/".$file."\" title=\"".$file."\" data-gallery=\"\"><img src=\"".$dir . $folder . "/".$file."\" style=\"height:100px; width:100px;\"></a>
                                  </div>
                            ";
                        }
                    }
                }
        }
    }
    closedir($handle);
}
?>

EDIT: following @JazZ suggestion, I have adjusted the code and it works well now, however, assuming that one does not want to display the resized pictures itself, but rather thumbnails stored in a subfolder (eg. ./location1/thumbs/), how would I go about this?

<?php                   
$dir = './inspections/';
if ($handle = opendir($dir)) {
    $blacklist = array('.', '..', 'default', 'default.php', 'desc.txt');
    while (false !== ($folder = readdir($handle))) {
        if (!in_array($folder, $blacklist)) {

                    echo "
                        <!-- Post -->
                        <div class=\"post\">
                          <div class=\"user-block\">
                            <img class=\"img-circle img-bordered-sm\" src=\"../dist/img/logo/gallery_icon_".$chain.".jpg\" alt=\"\">
                                <span class=\"username\">
                                  <a href=\"".$website."\" target=\"_blank\">".$hotel_name."</a>".$status."
                                </span>
                            <span class=\"description\"><i class=\"fa fa-map-pin\"></i> ".$location." - Posted on ".date('jS F, Y - H:m', strtotime($posted_on))."</span>
                          </div>
                          <!-- /.user-block -->

                          <p>".$desc."</p>
                          <div class=\"lightBoxGallery\">
                    ";

                    foreach (glob($dir . $folder . "/*.jpg") as $filename) {
                        echo "
                            <a href=\"".$filename."\" title=\"\" data-gallery=\"\"><img src=\"".$filename."\" style=\"height:100px; width:100px;\"></a>";
                    }
                    echo "</div>
                        </div>
                        <!-- /. POST -->

                        ";

        }
    }
    closedir($handle);
}
?>

Solution

  • I think your issue comes from here :

    while (false !== ($file = readdir($handle))) // it reads again the same directory as it did in the first while loop
    

    Try to replace it with

    if ($sub_handle = opendir($dir . $folder)) {
        while (false !== ($file = readdir($sub_handle))) {
            ...
        }
        closedir($sub_handle);
    }
    

    Also, in your case, I would use php glob() function

    See a working example for your case :

    $dir = './inspections/';
    if ($handle = opendir($dir)) {
        $blacklist = array('.', '..', 'default', 'default.php', 'desc.txt');
        while (false !== ($folder = readdir($handle))) {
            if (!in_array($folder, $blacklist)) {
                foreach (glob($dir . $folder . "/*.png") as $filename) {
                    echo "$filename was found !";
                    echo "\r\n";
                }
            }
        }
        closedir($handle);
    }
    

    Output :

    ./inspections/location_4/img_1.png was found !
    ./inspections/location_4/img_2.png was found !
    ./inspections/location_4/img_3.png was found !
    ./inspections/location_4/img_4.png was found !
    ./inspections/location_4/img_5.png was found !
    ./inspections/location_4/img_6.png was found !
    ./inspections/location_3/img_1.png was found !
    ./inspections/location_3/img_2.png was found !
    ./inspections/location_3/img_3.png was found !
    ./inspections/location_3/img_4.png was found !
    ./inspections/location_3/img_5.png was found !
    ./inspections/location_3/img_6.png was found !
    ./inspections/location_2/img_1.png was found !
    ./inspections/location_2/img_2.png was found !
    ./inspections/location_2/img_3.png was found !
    ./inspections/location_2/img_4.png was found !
    ./inspections/location_2/img_5.png was found !
    ./inspections/location_2/img_6.png was found !
    ./inspections/location_1/img_1.png was found !
    ./inspections/location_1/img_2.png was found !
    ./inspections/location_1/img_3.png was found !
    ./inspections/location_1/img_4.png was found !
    ./inspections/location_1/img_5.png was found !
    ./inspections/location_1/img_6.png was found !
    

    EDIT

    To loop in the /inspections/location1/thumbs/ directories, this would work :

    foreach (glob($dir . $folder . "/thumbs/*.png") as $filename) {
        echo "$filename was found !";
        echo "\r\n";
    }
    

    RE-EDIT

    To glob multiple folders with the glob() function, your code should look like :

    foreach (glob($dir.$folder."{/thumbs/*.png,/*.png}", GLOB_BRACE) as $filename) {
        echo "$filename was found !";
        echo "\r\n";
    }