PHP gallery from directory doesn't sort pics in order

Hi there,

I’ve done a php gallery using this script

  <?php
$folder_path = 'images/antidote_2018/'; //image's folder path

$num_files = glob($folder_path . "*.{JPG,jpg,gif,png,bmp}", GLOB_BRACE);

$folder = opendir($folder_path);


if($num_files > 0)
{
 while($file = readdir($folder))
 {
  $file_path = $folder_path.$file;
  $extension = strtolower(pathinfo($file ,PATHINFO_EXTENSION));
  if($extension=='jpg' || $extension =='png' || $extension == 'gif' || $extension == 'bmp')
  {
   ?>
            <li><img src="<?php echo $file_path; ?>"/></li></a>
            <?php
  }
 }
}
else
{
 echo "Le dossier est vide !";
}
closedir($folder);
?>

It’s working fine, the only problem is that pictures don’t sort by filename (pic001.jpg, pic002.jpg, …)

Could someone help me to fix it ?

I thank you in advance.

First thing, remove your logic from your html page. Do the processing first, so instead of the <li>s being made in your while loop, build an array of file names to use later.
Once you have your array, you can sort it with asort().

Then in your html page, output the list with a foreach loop.

Thank you for your fast answer.

I should have tell you that I’m not comfortable with PHP…

:blush:

The controller script could be something like:-

<?php
$folder_path = 'images/antidote_2018/'; //image's folder path

$num_files = glob($folder_path . "*.{JPG,jpg,gif,png,bmp}", GLOB_BRACE);

$folder = opendir($folder_path);


if($num_files > 0)
{
 $images = array();		// Set array only if there are images
 while($file = readdir($folder))
 {
  $file_path = $folder_path.$file;
  $extension = strtolower(pathinfo($file ,PATHINFO_EXTENSION));
  $imgext = array('jpg', 'png', 'gif', 'bmp');
  if(in_array($extension, $imgext))	// Look for extension in array
  {
   $images[] = $file_path	// Add the filename to the list
  }
 }
 //$images = asort($images);	// Sort the array into order
 asort($images);    // Correction as per post #5
}
closedir($folder);

require_once "gallery_html.php";	// Include the html page
?>

Then within your html template file something like:-

<?php if(isset($images)) : ?>
<ul class="gallery">
	<?php foreach($images as $file): ?>
	<li><img src="<?= $file ?>"></li>
	<?php endforeach ?>
</ul>
<?php else : ?>
<p>Le dossier est vide !</p>
<?php endif ?>

There is still a bit of messy logic in the html, but far less than you had before.

[off-topic]
Also take care of your html validation.

<li><img src="<?php echo $file_path; ?>"/></li></a>

You appear to be within a list, but have a stray closing </a> outside of the <li> element.

echo "Le dossier est vide !";

The message is uncontained, apparently within the list element.
[/off-topic]

1 Like

I’m not so sure you want

$images = asort($images); 

wouldn’t that change the variable from an array into a boolean?

http://php.net/manual/en/function.asort.php

Returns TRUE on success or FALSE on failure.

Similarly, I don’t know how well

if($num_files > 0) 

would work. i.e. “if array or false is greater than zero”

http://php.net/manual/en/function.glob.php

Returns an array containing the matched files/directories, an empty array if no file matched or FALSE on error.

3 Likes

I should have be more clear in my explanations…

Here is the whole original page :

<!DOCTYPE html>
<html lang="en">

<head>
  <title>XXX</title>
  <meta charset="utf-8">
  <meta name = "format-detection" content = "telephone=no" />
  <link rel="icon" href="images/favicon.ico" type="image/x-icon">
  <link rel="stylesheet" href="css/grid.css">
  <link rel="stylesheet" href="css/style.css">
  <link rel="stylesheet" href="css/flexslider.css">
  <script src="js/jquery.js"></script>
  <script src="js/jquery-migrate-1.2.1.js"></script>
  <script src="js/jquery.equalheights.js"></script>
  <script type="text/javascript" src="js/jquery.flexslider.js"></script>


  <!--[if lt IE 9]>
  <script src="js/html5shiv.js"></script>
/>

  </div>
  <![endif]-->
</head>


<body>
<!--========================================================
                          HEADER
=========================================================-->
<header id="header">
  <div class="container">
    <div class="row">
      <div class="grid_12">
        <div class="socials-block">
          <ul class="socials1">
            <li><a href="XXX" target="_blank"><img src="images/fbduck.png"></a></li>
            <li><a href="XXX" target="_blank"><img src="images/ducktube.png"></a></li>
          </ul>
        </div>
      </div>
    </div>
  </div>
  <div id="stuck_container">
    <div class="container">
      <div class="row">
        <div class="grid_12">
          <h1>
            <a href="index.html"><img src="images/logo_gd.png">&nbsp; </a>
          </h1>
          <nav>
            <ul class="sf-menu">
              <li><a href="index.html">Home</a></li>
              <li><a href="index-1.html">Dates</a></li>
              <li class="current"><a href="index-3.html">Medias</a>
                <ul>
                  <li><a href="index-3.html#photos">Photos</a></li>
                  <li><a href="index-3.html#videos">Videos</a></li>
                  <li><a href="index-3.html#lyrics">Lyrics</a></li>
                </ul>
              </li>
              <li><a href="index-4.html">Band</a></li>
              <li><a href="store.html">Store</a></li>
			  <li><a href="press.html">Press</a></li>
			  <li><a href="index-5.html">Contact</a></li>
			  </ul>
            <div class="clearfix"></div>
          </nav>
        </div>
      </div>
    </div>
  </div>
</header>



<!--========================================================
                          CONTENT
=========================================================-->

<section id="photos" class="common">
  <div class="wrapper4">
    <div class="container">
      <div class="row">
        <div class="grid_12">
          <h3><a href="index-3.html">Back to galleries</a> </h3>
          <div class="heading3">
            <h2>Antidote Festival - 03.08.2018</h2>
          </div>
          <div class="row">
            <div class="flexslider">
      <ul class="slides">

    <?php
$folder_path = 'images/antidote_2018/'; //image's folder path

$num_files = glob($folder_path . "*.{JPG,jpg,gif,png,bmp}", GLOB_BRACE);

$folder = opendir($folder_path);


if($num_files > 0)
{
 while($file = readdir($folder))
 {
  $file_path = $folder_path.$file;
  $extension = strtolower(pathinfo($file ,PATHINFO_EXTENSION));
  if($extension=='jpg' || $extension =='png' || $extension == 'gif' || $extension == 'bmp')
  {
   ?>
            <li><img src="<?php echo $file_path; ?>"/></li></a>
            <?php
  }
 }
}
else
{
 echo "Le dossier est vide !";
}
closedir($folder);
?>
      </ul>
    </div>
          </div>
        </div>
      </div>
      </div>
        </div>
    </div>
  </div>
</section>



<!--========================================================
                          FOOTER
=========================================================-->
<footer id="footer">
  <div class="wrapper">
    <div class="container">
      <div class="row">
        <div class="grid_6">
          <div class="privacy-block">
            <span id="copyright-year"></span> &copy; Rebel Duck - <a href="http://www.opencom.ch" target="_blank">Webdesign by <img src="images/oc.png"></a>
            <!--{%FOOTER_LINK} -->
          </div>
        </div>
        <div class="grid_6">
          <div class="info-block">

          </div>
        </div>
      </div>
    </div>
  </div>
</footer>

<script src="js/script.js"></script>
<script charset="utf-8" type="text/javascript">
   $(window).load(function() {
      $('.flexslider').flexslider();
   });
</script>
</body>
</html>

Yes, my bad, it returns a boolean, missed that bit. You would just need:-

asort($images) ;

The rest of the script I presumed to be working with the exception of sorting, as the OP describes.

If this is, and always will be, the only page with the gallery, then you could get away with having all of the PHP code in the one file along with the HTML. But even then I think SamA74’s suggestion of moving the majority of the PHP out of the HTML is a good idea.

I would be tempted to put most of it in a function that takes the argument you give it and returns what you want. eg.

<?php
include 'my_custom_functions.php'; 
?> 
<!DOCTYPE html>
<html lang="en"> 
.....

where the “my_custom_functions” file has something like

function return_sorted_image_array($image_folder_path) { 
.......

then call the function in the templates where needed.

Each page takes pictures from the related folder (for ex. antidote.php takes pics from images/antidote_2018)

My problem is that if I put all the php in my html page, it doesn’t work at all…

I’m assuming you’ve made changes and the code is now broken. What are the error messages?

This prints the files in alphabetical order (1.jpg, a.jpg, b.jpg, pic001.jpg, pic002.jpg, pic003.jgp etc.) atleast when i quickly tested it.

$imgDir = './images';
$allowedExtensions = ['jpg', 'png', 'gif'];

foreach (new DirectoryIterator($imgDir) as $fileInfo) {
    if($fileInfo->isDot()) continue;
    if (in_array($fileInfo->getExtension(), $allowedExtensions)) {
        echo $fileInfo->getFilename() . "<br>\n";
        echo '<img src="'. $imgDir .'/'. $fileInfo->getFilename() .'"><br/>';
    }
}

I would never rely on behaviour like that from internal functions. There is no guarantee it will stay working like this (the manual on DirectoryIterator doesn’t mention anything on sorting), plus we don’t know why it’s working like this. Maybe it’s intentional in PHP, or maybe it’s how your filesystem works, and then when you run the code on other filesystem it doesn’t work anymore.

If you want an array to be sorted, sort it yourself, don’t rely on others to do it (except for stuff like SQL database ORDER BY of course, which sorts explicitly).

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.