Jump to content

How to scroll through files in a directory


db9

Recommended Posts

I have a function that reads all the picture files in a folder and displays them as thumbnails. It also displays a large version of the first image in the folder and clicking the thumbnail changes the large picture. I'm trying to use pictures of arrows as a button to allow users to click and have the next picture displayed large rather than having to click each individual thumbnail but don't really know how to get started. Can anyone suggest a method or give me a hint?

 

This is my code so far if that helps:

 

function displayPhotos(){

global $columns,$dir,$album;

generateThumbnails();

$act = 0;
$keyid = 0;

$thumb_selected = (isset($_GET['thumb']) ? $_GET['thumb']:'');

if ($thumb_selected !==""){

			$dirName  = substr($thumb_selected,0,strpos($thumb_selected,basename($thumb_selected)));
      			$thumbName = basename($thumb_selected);
			$thumbFile = $dirName.$thumbName;
			$large = str_replace('_th.jpg','.jpg',$thumbFile);
}

else{

$picture_array = glob("$dir*");

$large = $picture_array[$keyid];
}

echo "<tr><td colspan='3' height='300' width='400' align='center'><img src='$large' alt=''></td></tr>
<tr><td><img src='gallery/icons/arrow-blue-rounded-left.jpg' alt='Previous'></td><td></td><td align='right'><img src='gallery/icons/arrow-blue-rounded-right.jpg' alt='Next'>
        </td></tr><tr><td height='50'></td></tr>";

if ($handle = opendir("$dir")) {

	while (false !== ($file = readdir($handle)))  {

		$file=$dir.$file;

		if (is_file($file)){

      		if (strpos($file,'_th.jpg')){

				++$act;

				if ($act > $columns) {

					echo "</tr><tr><td width='160' height='120' align='center'><a href='?album=$album&thumb=$file'><img src='".$file."' alt='".$file."'/></a></td>";

					$act = 1;

				} else {

					echo "<td width='160' height='120' align='center'><a href='?album=$album&thumb=$file'><img src='".$file."' alt='".$file."'/></a></td>";	

				}    			

      		}

      	}

	}

}	

}

 

Thanks very much to anyone having a look at this!

Link to comment
Share on other sites

in the loop which prints the images, add an incremental integer, for instance ++$i;

 

then add an 'id' variable to the url. so it would read as /gallery.php?id=2 and by default it's 1.

the idea is that left arrow points to ?id=($_GET['id'] -1); and right arrow points to ?id=($_GET['id'] +1);

 

back to the loop -- add a condition: if($i == $_GET['id']) echo 'big image'; else echo 'thumbnail';

 

hope this makes sense

Link to comment
Share on other sites

Hi thanks very much for the help! I think I understand the gist of what you're saying but I'm not sure how to implement it. At the moment I don't actually have a loop displaying the large image at all. I have a loop that finds all the thumbnails (created in a separate function) and displays them and then the first bit either displays the first non-thumbnail image in the folder or if a thumbnail has been clicked then it displays the corresponding large image in place of the first.

 

How could I introduce a loop to this? Thanks again!

Link to comment
Share on other sites


$thumb_selected = (isset($_GET['thumb']) ? $_GET['thumb']:'');

if ($thumb_selected !==""){

$dirName  = substr($thumb_selected,0,strpos($thumb_selected,basename($thumb_selected)));

$thumbName = basename($thumb_selected);

$thumbFile = $dirName.$thumbName;

$large = str_replace('_th.jpg','.jpg',$thumbFile);

}

 

Wait, isn't this what should do it in the first place?

Link to comment
Share on other sites

Sorry if I haven't explained this very well.

 

That bit checks if a thumbnail image has been clicked on and if it has it finds the large version of the image clicked by striping the _th from the end and displays that picture in a separate space. That works fine but I'm trying to add backwards and forwards buttons so that you can use them to navigate through an album say, without having to click each thumbnail. I'm struggling to find a way to do it that doesn't break the bits I already have.

 

Thanks again!

Link to comment
Share on other sites

if you scan the directory every time the page is loaded, that is most likely not efficient to begin with.. But if it must be done, you only need to record the list as it goes thru.. and record the name of the image before the current one.. the current one.. and the next one after the current..

 

for example..

 

$getNext = (boolean) ($curr = ($prev = ($next = '')));
foreach ($images as $filename) {
  if ($getNext) { $next = $filename; break; }
  if ($filename == $_GET['requestedImage']) {
    $getNext = true;
    $curr = $filename;
    continue;
  }
  $prev = $filename;
}
// $next, $prev, $curr are what you're lookin for 

Link to comment
Share on other sites

Hi Void, thanks very much I think I'm getting closer! I've changed my code to:

 

function displayPhotos(){

global $columns,$dir,$album;

generateThumbnails();

$act = 0;
$keyid = (isset($_GET['keyid']) ? $_GET['keyid']:'0');

$Picturecount = (count(glob("" . $dir . "*.jpg")))/2;

$thumb_selected = (isset($_GET['thumb']) ? $_GET['thumb']:'');

if ($thumb_selected !==""){
$dirName  = substr($thumb_selected,0,strpos($thumb_selected,basename($thumb_selected)));
$thumbName = basename($thumb_selected);
$thumbFile = $dirName.$thumbName;
$large = str_replace('_th.jpg','.jpg',$thumbFile);
}

else{	
if($keyid > (2*$Picturecount-1)){
$keyid = ($keyid - (2*$Picturecount));
}
if($keyid < 0){
$keyid = (2*$Picturecount-2);
}	

$picture_array = glob("$dir*");

$large = $picture_array[$keyid];

}

echo "<tr><td colspan='3' height='300' width='400' align='center'><img src='$large' alt=''></td></tr>
<tr><td><a href='?album=$album&keyid=" . ($_GET['keyid']-2) . "'>Previous</a></td><td></td><td align='right'><a href='?album=$album&keyid=" . ($_GET['keyid']+2) . "'>Next</a></td></tr><tr><td height='50'></td></tr>";

if ($handle = opendir("$dir")) {
while (false !== ($file = readdir($handle)))  {
$file=$dir.$file;
if (is_file($file)){
if (strpos($file,'_th.jpg')){
++$act;
if ($act > $columns) {
echo "</tr><tr><td width='160' height='120' align='center'><a href='?album=$album&thumb=$file'><img src='".$file."' alt='".$file."'/></a></td>";
$act = 1;
} else {
echo "<td width='160' height='120' align='center'><a href='?album=$album&thumb=$file'><img src='".$file."' alt='".$file."'/></a></td>";
}}}}}}

 

This seems to work as far as it goes my if statement doesn't work very well though. At the moment if the keyid goes above 2*the number of pictures then it doesn't go back to the start and if the keyid goes below 0 then it just gets set to zero permanently. Can you suggest a fix or a better way of doing this? Basically I want it to work so that if you're on the last picture and you click next it goes back to the start and if you're on the first and click previous it goes to the last (is there a way to reset the URL maybe?)

 

Thanks a lot for the help!

 

RussellReal, Thanks very much for the help am trying Void's solution at the moment as that seems to have almost cracked my problem but thanks again. The reason I have it scan the directory every time the page is loaded is because I want to be able to update it by just copying a new photo album into the appropriate folder and then having the page do everything else so obviously I need it to check whether anything new has been added whenever it's loaded.

Link to comment
Share on other sites

I'd have my routine read through the files on the server building up an array in Javascript containing all the filenames.

 

Then you can have a viewer where you use "onclick" events for the next and previous buttons where you have something like:

<img src="pictures/firstpic.jpg" id="picviewer">

 

Then something like this for the buttons:

<input type="button" value="Prev" onclick="showPreviousPicture()">

 

Inside the javascript function showPreviousPicture() you would have something like:

document.getElementById("picviewer").src=arrPicList[num-1];

Link to comment
Share on other sites

Okies 

In that case you're going to need to be refreshing the page each time.

This means you'll be scanning the pictures folder each time - as you build up the list of files build an array at the same time and default the first picture to view as 1 if the index number isn't set on the URL:
[code=php:0]$intPicNum=(isset($_GET['pic']) ? intval($_GET['pic']) : 1);

 

Now for the next/prev buttons:

<a href="picviewer.php?pic=<?php echo ($intPicNum-1); ?>">Prev</a>

<a href="picviewer.php?pic=<?php echo ($intPicNum+1); ?>">Next</a>

 

Of course, you'll need to add checks in there at $intPicNum is already at the first or last picture - no need to make the "next" link if the user is at the last picture already!

Link to comment
Share on other sites

Thanks for sticking with this. I realise this is a bit cheeky but I'm not really sure which bit of my code your bit replaces?

 

This is what I'm using:

 

function displayPhotos(){

global $columns,$dir,$album;



generateThumbnails();

$act = 0;

$keyid = (isset($_GET['keyid']) ? $_GET['keyid']:'0');



$thumb_selected = (isset($_GET['thumb']) ? $_GET['thumb']:'');



if ($thumb_selected !==""){

			$dirName  = substr($thumb_selected,0,strpos($thumb_selected,basename($thumb_selected)));

      			$thumbName = basename($thumb_selected);

			$thumbFile = $dirName.$thumbName;

			$large = str_replace('_th.jpg','.jpg',$thumbFile);

}



else{		

$picture_array = glob("$dir*");

$large = $picture_array[$keyid];

}
echo $keyid;


echo "

<tr><td colspan='3' height='300' width='400' align='center'><img src='$large' alt=''></td></tr>

<tr><td><a href='?album=$album&keyid=" . ($_GET['keyid']-2) . "'>Previous</a></td><td></td><td align='right'><a href='?album=$album&keyid=" . ($_GET['keyid']+2) . "'>Next</a></td></tr><tr><td height='50'></td></tr>";



	$thumb_array = scandir($dir);  

		foreach($thumb_array as $file){

      		if (strpos($file,'_th.jpg')){

				++$act;

				if ($act > $columns) {L

					echo "</tr><tr><td width='160' height='120' align='center'><a href='?album=$album&thumb=$dir$file'><img src='".$dir.$file."' alt='".$dir.$file."'/></a></td>";

					$act = 1;

				} else {

					echo "<td width='160' height='120' align='center'><a href='?album=$album&thumb=$dir$file'><img src='".$dir.$file."' alt='".$dir.$file."'/></a></td>";	

				}

      			

      		}

      	}

}

 

Is there any chance you could show me what it should look like? Thanks again!

Link to comment
Share on other sites

I don't know if you can use any of this source - feel free - I wrote this ages ago to list all the files inside a specific folder on the server building up a multi dimensional array where the files and dirs are split into two groups.

 

<?php
  /**************************************************************
  ** Get the contents of a directory                           **
  ** Place the contents into an array then sort alphabetically **
  **************************************************************/
  $strDirName=$_SERVER['DOCUMENT_ROOT']; //PATH
  $arrContents=array('dir' => array(),'file' => array()); //MAKE ARRAY
  $strMessage='';
  if ($ptrLock=@opendir($strDirName)) { //GET DIRECTORY LOCK
    clearstatcache();
    while (false!==($strFilename=@readdir($ptrLock))) {
      if ($strFilename!='.'&&$strFilename!='..') { //IGNORE "." AND ".."
        if (is_dir($strDirName.'/'.$strFilename)) { //IS THE ENTRY A DIRECTORY?
          array_push($arrContents['dir'],$strFilename); //YES
        } else {
          array_push($arrContents['file'],$strFilename); //NO
        }
      }
    }
    sort($arrContents['dir']); //SORT THE DIRECTORIES
    sort($arrContents['file']); //SORT THE FILES
    closedir($ptrLock); //RELEASE THE DIRECTORY LOCK
  } else {
    $strMessage='ERROR: Unable to lock directory ('.$strDirName.')';
  }
  if (isset($_GET['debug'])) {
    var_dump($arrContents);
  }
?>
<html>
<head>
  <title>Dir Test</title>
  <style type="text/css">
    td {font: 10px verdana}
  </style>
</head>
<body>
<?php
  if (empty($strMessage)) {
    echo '<table cellspacing="1" cellpadding="0" border="0">';
    echo '<tr><td colspan="2">Directory: '.$strDirName.'/</td></tr>';
    for ($i=0;$i<count($arrContents['dir']);$i++) { //SHOW THE DIRECTORIES
      echo '<tr><td width="17"><img src="gfx/folder.gif" alt="Folder" width="16" height="16" border="0" /></td><td>'.$arrContents['dir'][$i].'</td></tr>';
    }
    for ($i=0;$i<count($arrContents['file']);$i++) { //SHOW THE FILES
      $tmp=explode('.',$arrContents['file'][$i]);
      $strFileExt=strtolower($tmp[count($tmp)-1]);
      switch ($strFileExt) {
        case 'php':$strFileType='php';break;
        case 'gif':
        case 'jpeg':
        case 'jpg':$strFileType='picture';break;
        case 'htm':
        case 'html':$strFileType='html';break;
        default:$strFileType='file';
      }
      echo '<tr><td width="17"><img src="gfx/'.$strFileType.'.gif" alt="File" width="16" height="16" border="0" /></td><td>'.$arrContents['file'][$i].'</td></tr>';
    }
    echo '</table>';
  } else {
    echo $strMessage;
  }
?>
</body>
</html>

Link to comment
Share on other sites

Hi thanks for the continued help. I'm slowly getting further at the moment I've got it so that clicking the next arrow loads the next image in the appropriate space in large and clicking a specific thumbnail loads that image in large. However with the arrows I'm using a keyid variable to return the correctly sequenced picture from the array of pictures but with the thumbnails I'm just loading the file path. This obviously means that using both means the pictures aren't kept in sequence when scrolling through.

 

i.e. if you press the next arrow then click the 4th thumbnail and then click the next arrow again it loads the 2nd picture rather than the 5th as it should.

 

Is there a way to query the array so that I can take the thumbnail file path and use that to return the keyid that it corresponds to?

 

This is my code:

 


global $columns,$dir,$album;

generateThumbnails();

$act = 0;

$keyid = (isset($_GET['keyid']) ? $_GET['keyid']:'0');

$thumb_selected = (isset($_GET['thumb']) ? $_GET['thumb']:'');

if ($thumb_selected !==""){
$dirName  = substr($thumb_selected,0,strpos($thumb_selected,basename($thumb_selected)));
$thumbName = basename($thumb_selected);
$thumbFile = $dirName.$thumbName;
$large = str_replace('_th.jpg','.jpg',$thumbFile);
}
else{	

if($keyid > (2*$Picturecount-1)){

$keyid = ($keyid - (2*$Picturecount));

}

if($keyid < 0){

$keyid = (2*$Picturecount+$keyid);

}

echo "
<tr><td colspan='3' height='300' width='400' align='center'><img src='$large' alt=''></td></tr>

<tr><td><a href='?album=$album&keyid=" . ($_GET['keyid']-2) . "'>Previous</a></td><td></td><td align='right'><a href='?album=$album&keyid=" . ($_GET['keyid']+2) . "'>Next</a></td></tr><tr><td height='50'></td></tr>";

$thumb_array = scandir($dir);  
foreach($thumb_array as $file){
if (strpos($file,'_th.jpg')){
++$act;
if ($act > $columns) {
echo "</tr><tr><td width='160' height='120' align='center'><a href='?album=$album&thumb=$dir$file'><img src='".$dir.$file."' alt='".$dir.$file."'/></a></td>";
$act = 1;
} else {
echo "<td width='160' height='120' align='center'><a href='?album=$album&thumb=$dir$file'><img src='".$dir.$file."' alt='".$dir.$file."'/></a></td>";
}
}
}
}

Apologies if that wasn't explained very well and thanks again for all the help!

Link to comment
Share on other sites

Hi, thanks a lot to anyone still reading this. I've changed my code a bit so I think it's easier to see what's going on. My problem now is basically that when I press next or previous the keyid is reset. I'd like it to carry on from the last thumbnail selected if one has been clicked.

 

Would be very greatful if anyone can help me with this. Thanks

 

This is my code:

generateThumbnails();

$act = 0;

$keyid = (isset($_GET['keyid']) ? $_GET['keyid']:'0');



$Picturecount = (count(glob("" . $dir . "*.jpg")))/2;



$thumb_selected = (isset($_GET['thumb']) ? $_GET['thumb']:'');


$picture_array = glob("$dir*");


if ($thumb_selected !==""){

			$dirName  = substr($thumb_selected,0,strpos($thumb_selected,basename($thumb_selected)));

      			$thumbName = basename($thumb_selected);

			$thumbFile = $dirName.$thumbName;

			$selected = str_replace('_th.jpg','.jpg',$thumbFile);


        foreach ($picture_array as $search){
$keyid = array_search($selected,$picture_array);
$large = $picture_array[$keyid];
}}


else{	

if($keyid > (2*$Picturecount-1)){

$keyid = ($keyid - (2*$Picturecount));}

if($keyid < 0){

$keyid = (2*$Picturecount+$keyid);}


$large = $picture_array[$keyid];}

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.