Scanning Folders with PHP
Nov 13th in Screencasts by Jeffrey Way
Let's imagine that you want to build a page that will display snapshots of your latest work. One way to do this would be to hard-code the images into your document. The obvious repercussion is that, every time you want to add a new item, you must manually update your html document. Another method would be to store and retrieve the information from a MYSQL database. This will function perfectly, though for many sites, this solution may possibly offer far more power than is technically needed - not to mention the increase in hosting costs.
In such instances, the best solution is to make PHP scan your "portfolio" folder and dynamically create the code for you. If you want to update your page with a new snapshot, all that you need to do is drag the image, and its respective thumbnail, into the appropriate folders - and PHP will do the rest. Let's build it now!
Hi, I'm Jeff. I'm the editor of NETTUTS, and the Site Manager of Theme Forest. I spend too much time in front of the computer and find myself telling my fiance', "We'll go in 5 minutes!" far too often. I just can't go out to dinner while I'm still producing FireBug errors...drives me crazy. I love the ASP.NET framework, jQuery, PHP, CSS, AJAX - pretty much anything.
Our Mission
Let's briefly outline what we need to accomplish.
- Use PHP to scan our portfolio folder. It will then cyle through each file, that is an image, and then display it on the page.
- Style our content a bit using CSS.
- When the users clicks on a thumbnail, we'll use jQuery to load the large version of the image in the main panel.
- If the user has Javascript disabled, he'll simply be directed to a new page that contains the full-sized image
How to Use It
Adding a new image to our portfolio is simple. Take a snapshot of your website, brochure, postcard, etc and size it to 500px x 350px. Place this image within the "images/featured" folder.
Next, create a thumbnail that is 50px x 50px. Place this image within the "images/tn" folder.
You must make sure that both the full-sized and the thumbnail images have the exact same file name.
Our Final HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Scanning Directories with PHP</title>
<script src="js/jquery-1.2.6.pack.js" type="text/javascript"></script>
<script src="js/scripts.js" type="text/javascript"></script>
<link href="default.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="container">
<h1>Some Portfolio</h1>
<div id="featured">
<?php
$featured_dir = 'images/featured/';
$scan = scandir($featured_dir);
echo '<img src="'. $featured_dir . $scan[2] . '" alt="image" />';
?>
</div>
<ul id="options">
<?php
$dir = 'images/tn/';
$scan = scandir($dir);
for ($i=0; $i<count($scan); $i++) {
if ($scan[$i] != '.' && $scan[$i] != '..') {
echo '
<li>
<a href="' . $featured_dir . $scan[$i] . '">
<img src="'. $dir . $scan[$i] . '" alt="'. $scan[$i] . '" />
</a>
</li>';
}
}
?>
</ul>
</div>
</body>
</html>
Our Final CSS
View it here.
Compensating For IE6
Luckily, we only have one thing to fix. If you look at the image above, you'll see that the #options unordered list is not containing its floated list items. While modern browsers will correctly clear the items thanks to our "overflow: hidden;" style, IE6 needs one more rule. Append this to your stylesheet.
ul#options {
...misc styles...
height: 1%;
}
I could have set the height to anything and it would still work. Think of it as Drago punching IE6 in the face and telling it, "Wake up!". This style forces IE6 to expand as much as is need to clear its children.
The Complete Javascript(jQuery)
$(function() {
$.preloadImage = function(path) {
$("#featured img").attr("src", path);
}
$('ul#options li img').click(function() {
$('ul li img').removeClass('selected');
$(this).addClass('selected');
var imageName = $(this).attr('alt');
$.preloadImage('images/featured/' + imageName);
var chopped = imageName.split('.');
$('#featured h2').remove();
$('#featured')
.prepend('' + chopped[0] + '
').children('h2').fadeIn(500).fadeTo(200, .6);
});
$('ul#options li a').click(function() {
return false;
});
});
Extra Credit
There are ways to create thumbnails of our images dynamically. Try to find a way to make PHP scan our "featured" folder and then dynamically create a thumbnail version and save it within the "tn" folder.
- Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.
User Comments
( ADD YOURS )Jeffrey Way November 13th
Are you guys hearing that obnoxious high-pitched hum in the video? Or is it just my laptop? So strange…I may have to reconvert the video and update this posting.
insic November 13th
Nice tutorial Jeff. I dont hear the hum youve mentioned. the audio is so clear.
Josh November 13th
I hear the high-pitched hum randomly in the background audio, but it’s not that distracting. Thanks for the great tut!
Shane November 13th
Hi Jeff! Nope, no hum for me. Thanks for posting the tutorial!
Gregorio Ramirez November 13th
Awesome time-saver function!
Craigsnedeker November 13th
Looks awesome!
Thomas Milburn" November 13th
Just a quick note if you can’t get this to work, scandir is only available in PHP5. If you have PHP4 use:
$dh = opendir($dir);
while (false !== ($filename = readdir($dh))) {
$files[] = $filename;
}
sort($files);
Miles Johnson November 13th
You could also use glob() to scan a directory… it actually adds more support for getting certain filetypes.
http://us3.php.net/glob
Sam Smith November 13th
What a coincidence, I just did this for a personal project a few weeks ago! I’m part of a team that’s writing a software packing which includes an installable on windows mobile phones. The other team members had been loading the .exe onto an SD card and taking it from phone to phone (about 20 in all) and installing it one at a time.
Knowing that the phones had wi-fi, I wrote a quick, 25-line PHP script just like this to read the contents of the installer directory and print out links on a webpage. It was MUCH easier to go to the page, click the link, and install than by going one at a time.
Anton Lindqvist November 13th
Great tutorial!
You might put somethings similiar to this inside the for-loop so all hidden files while be excluded.
if(!preg_match(’/^\./’,$scan[$i]))
Sean November 13th
Unless you have a specific need, I find foreach($array as $key => $val) to be far handier.
Then you can just access $val, and not worry about a counter variable.
Though it makes little difference.
dmoena November 13th
Nice one. I just miss the upload form with automatic thumbnail generation
otherwise, is a quite useful tool
Yosy November 13th
Excellent as usual

Thanks allot Jeff
THEMOLITOR November 13th
I’d be interested in seeing the auto thumbnail generator you mentioned in the extra creadit
Lamin November 13th
Great tut Jeff. Thanks
Vince November 13th
@THEMOLITOR
The extra credit means: now that you know how to do this. go figure out how to do that.
Keith November 13th
Thanks Jeffery,
Fantastic tutorial, thank you. More PHP!
Jeffrey Way November 13th
Yeah - I think I’ll do another screencast that shows how to auto-generate the thumbnails.
These videos are tough because I want to cover so much, but there just isn’t enough time. Things must be sacrificed.
Moksha November 13th
thanks Jeff, was looking for Video Tutorial.
Barttos November 13th
@Jeffrey Way, this is a little bug of Camtasia Studio, and a specific version of Adobe Flash Player.
ps. great tutorial! Next tutorial will be about a protofolio on php and xml? :))
Barttos November 13th
Jeffrey Way, what you use for generating thumbnails?
Jeffrey Way November 13th
@Sean - Good point.
@Barttos - Ahh. thanks.
@Anton - Nice. I was looking for a regular expression like that. I’m just lazy.
I’ll be sure to save that expression for future use.
Jackson November 13th
Is there a possibilty to cover the same tutorial in ASP.NET with C#. That would be really nice.
blankyao November 13th
so cool
RyanP November 13th
It’s like you guys knew what I was looking to do. I’ve been working on doing this, but with a flash photo viewer.
Awesome!
TheDoc November 13th
Great stuff Jeff, these types of tutorials are what keep me coming back to NETTUTS. Thanks!
Daniel Cousineau November 13th
The more commonly accepted method of scanning a directory nowadays is using the SPL’s DirectoryIterator.
foreach( new DirectoryIterator(’./’) as $item )
{
if( $item->isFile() )
{
$item->getFilename(); // file.txt
$item->getPathname(); // /path/to/file.txt
}
elseif( $item->isDot() ) //is . or ..
{ }
elseif( $item->isDir() )
{ }
}
Even more advanced traversals, like scanning all sub directories, can be done with a RecursiveIteratorIterator and RecurisveDirectoryIterator:
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(’./’)) as $item)
{
//…
}
Daniel Cousineau November 13th
Oh, and you can find all the methods you have access to on DirectoryIterator objects from PHP’s website at: http://docs.php.net/directoryiterator
Mike November 13th
Net toots?
Jhay November 13th
Looks good. Thanks!
Jeffrey Way November 13th
@Mike - Yeah, you can say it either way. I use both.
ashvin November 13th
thumbnails auto-generation is my nightmare! im waiting for its screencast!
keep on with your sweet php tuts man!
weblizzer November 13th
great tutorial jeff, i’m very much glad you are now venturing into php.. great!
yaheed November 13th
Really nice to see the editor of such a great tut website actively posting tutorials himself. Legend!
jbcarey November 13th
http://matencafe.maes.be/matencafe/benl/inzendingen
used this code a few weeks ago on here…. good stuff
Shane November 14th
@Jackson - an ASP.NET version would be pretty easy to do. @Jeffrey - I hope you don’t mind me posting C# in a PHP discussion:
The code below will generate images. Firstly, generate a website, place a Literal control on your page with the ID ‘LiteralImages’, and place this in the page’s Page_Load method:
if (!Page.IsPostBack)
{
// use a string builder to build our output:
System.Text.StringBuilder outputBuilder = new System.Text.StringBuilder();
// define the sub-directory:
string relativeDirectory = “img/”;
string absoluteDirectory = Server.MapPath( relativeDirectory);
// get the image files:
System.IO.FileInfo[] imageFiles =
new System.IO.DirectoryInfo(absoluteDirectory).GetFiles(”*.jpg”);
// loop through, building up the output:
foreach (System.IO.FileInfo currentImage in imageFiles)
{
outputBuilder.AppendFormat(
@”", currentImage.Name,
relativeDirectory);
}
// set the Text property of the literal control
// (a control that we’ve placed on the ASPX page):
LiteralImages.Text = outputBuilder.ToString();
}
Obviously not as feature rich as Jeffrey’s tutorial, but hopefully enough to get you started. As I write this, I just hope that the code is displayed properly
Hahn November 14th
i’m really looking forward for your 2nd part of Create a Photo Admin Site Using PHP and jQuery and i hope you can teach and show how to tag and search for the photos too. Also, i hope there would be 2 types of users. One is the administrator and the other is the registered member.
Eduardo November 14th
No coments at all !!
Jean-Francois November 14th
Many Thanks Jeff for this great tutorial
Frank November 14th
I made a script/class that scans all images and makes thumbnails too.
http://61924.wepwnyou.net/projects/imgbrowz0r.html
Rijalul Fikri November 14th
Will try this for sure
Takumi86 November 14th
Great, absolutely great, i’m saving those script for later use, thanks
Renzo November 14th
Amazing tutorial. Thanks.
Sebastian November 14th
“is slowly getting there, pretty quickly”
awesome tut, thx!
Terry November 14th
How can this error be fixed
Fatal error: Call to undefined function: scandir() in /home/sites/eireloom.com/public_html/index.php on line 17
my php versions
PHP
4.4.8
PHP5
5.2.5
Alex November 14th
awesome awesome stuff,
keep up the good work!
jbcarey November 15th
thx for this Mr. Way. Another good script! (although some pagination would have been good too)
jbcarey November 15th
oh and….
http://nicof.be/jbcarey/nettuts/ReadFolders/ this is my “result”
Dan Gayle November 16th
You could use this same code to “automatically” create navigation for a “dymamic” website that consisted purely of flat file PHP pages. That would be awesome. The ultimate “static” website!
Vikram S. Haer November 16th
This is awesome. I worked on a student group website (http://californians.berkeley.edu) and I was thinking of something like this for our newsletter listing. I’m still really new at this stuff and am probably gonna use the concepts shown here to implement an auto-updating list of newsletters. Thanks again jeff! (still waiting on the photo gallery part 2 tho :P)
Vikram S. Haer November 16th
One question: If we were working with a list of files (pdfs in my case) and wanted to sort them a specific way, is there any way we could do so? For me, I wanted to sort the list by date since I want most recent newsletters to appear at the top. Any help would be appreciated.
http://californians.berkeley.edu I noticed the link didn’t work above so thought i’d try retyping it without the parens.
iexx November 18th
In additional You can add a Exif PHP functions for getting Image exif information
Alex November 21st
2Jeffrey Way
Thnx, but…
If 500 images in folder…?
May be create listing (1 page = 50 pics)
We want see video “How get listing ?”
Sean November 29th
Hey, a question, how would it be possible to have a button go to the next image in the list?
tisodotsk November 30th
Great tutorial for beginers, but with programmatical mistakes in PHP:
- better than scandir() (witch returns folders and files) is work with files only - glob() or some user function can do that.
- foreach($scan as $val) is better than for($i=0;$i<count($scan);$i++), you don’t need to now how many files are there, you only need process all of them.
Jetoine December 15th
I’m almost a total NOOB! how can I modify this code to say scan a text based html filesystem and create dynamic links.
I have a number of growing folders that contain html stories and I need a way to organize them.
a modification of this code could work for an index system right?
Terminal December 17th
I use this bit of code instead, this way I don’t have to make a thumbnail. I use it to display wallpapers I make. Since I don’t know RegEx, this is the best way for me:
<?php
function getFileDetails($dir)
{
$files = array();
$allowed = array(’jpg’, ‘gif’, ‘png’);
$i = 0;
if ( ($h = opendir($dir)) == false )
{
die(’Error: Could not open directory.’);
}
while ( false !== ($file = readdir($h)) )
{
$parts = explode(’.', $file);
$cnt = count($parts)-1;
$ext = $parts[$cnt];
if ( in_array($ext, $allowed) == true )
{
$files[$i]['filename'] = $parts[0];
$files[$i]['filelink'] = $dir.$file;
$dimensions = getimagesize($dir.$file);
$files[$i]['filedim'] = $dimensions[0].’ x ‘.$dimensions[1];
$kb = number_format(filesize($dir.$file)/1024, 0, ”, ”).’ kb’;
$mb = number_format($kb/1024, 2, ‘.’, ”).’ mb’;
$files[$i]['filesize'] = $kb.’ (’.$mb.’)';
$files[$i]['filetype'] = ( $ext == ‘jpg’ ) ? strtoupper(’jpeg’) : strtoupper($ext);
$i++;
}
}
$h = closedir($h);
return $files;
}
function FileDetailsList($dir)
{
$files = getFileDetails($dir);
$list = ”;
for ( $i = 0; $i < count($files); $i++ )
{
$thumbsrc = ‘data:image/jpeg;base64,’.base64_encode(exif_thumbnail($files[$i]['filelink']));
$list .= ‘‘.$files[$i]['filename'].’‘;
$list .= ”;
$list .= ‘Preview: ‘;
$list .= ‘Screen Resolution: ‘.$files[$i]['filedim'].”;
$list .= ‘Filesize: ‘.$files[$i]['filesize'].”;
$list .= ‘Image Type: ‘.$files[$i]['filetype'].”;
$list .= ”;
$list .= ”;
}
$list .= ”;
return $list;
}
?>
Terminal December 17th
That last function should be this, sorry!
function FileDetailsList($dir)
{
$files = getFileDetails($dir);
$list = ‘<ul>’;
for ( $i = 0; $i Preview:</span> <a href=”‘.$files[$i]['filelink'].’”><img src=”‘.$thumbsrc.’” /></a></li>’;
$list .= ‘<li><span>Screen Resolution:</span> ‘.$files[$i]['filedim'].’</li>’;
$list .= ‘<li><span>Filesize:</span> ‘.$files[$i]['filesize'].’</li>’;
$list .= ‘<li><span>Image Type:</span> ‘.$files[$i]['filetype'].’</li>’;
$list .= ‘</ul>’;
$list .= ‘</li>’;
}
$list .= ‘</ul>’;
return $list;
}
Terminal December 17th
i need a preview comment button! anyways, this was the import part of the 2nd function:
$thumbsrc = ‘data:image/jpeg;base64,’.base64_encode(exif_thumbnail($files[$i]['filelink']));
although when rendered, the source is HUGE
Ryan Edick December 30th
This is a great tutorial and exactly what I need for a project of mine!
I am wondering though, in the if statement you said you could exclude certain file types, is there is a way to exclude an entire file?
I have a file within the directory I am scanning and it is being added to the array. If anyone can help me to add the exception to the if statement that would help me a ton!
thanks!
Add Your Comment
( GET A GRAVATAR )Your Name January 9th
Trackbacks