Miscellaneous
  Home arrow Miscellaneous arrow Page 3 - Creating an Image Gallery
Codewalker Forums 
  Tutorials  
Database Articles  
Miscellaneous  
Navigation Usability  
PEAR Articles  
Programming Basics  
Server Administration  
XML Tutorials  
  Reviews  
Database Book Reviews  
Linux Book Reviews  
Miscellaneous Reviews  
PHP Book Reviews  
PHP Software Reviews  
Server Admin Reviews  
SQL Tool Reviews  
  Code Gallery  
Content Management Code  
Contest Code  
Counters Code  
Database Code  
Date Time Code  
Discussion Board Code  
Email Code  
File Manipulation Code  
GUI Code  
Link Farm Code  
Miscellaneous Code  
Search Code  
Site Navigation Code  
User Management Code  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
Download TestComplete 
Forums Sitemap 
Weekly Newsletter 
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
MISCELLANEOUS

Creating an Image Gallery
By: notepad
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 8
    2003-10-24

    Table of Contents:
  • Creating an Image Gallery
  • getting started
  • moving along
  • review and organize
  • thumbnails
  • conclusion

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Creating an Image Gallery - moving along


    (Page 3 of 6 )

    our next script (images.php) we'll almost have to write backwards. we already know what we want, so the idea is to write one thing at a time, and then organize that information as we move along. in other words, the last function we write may very well end up being the first function to appear in the script. so long as we focus on one task at a time, the script will come together wonderfully.

    since we're only working with the file system as our database, our first task should be to traverse the directory specified within our configuration file and gather its contents into an associative array. our first line of code will include the config file so we have access to the path (along with the other values we'll need later).

    <?php
    require_once('config.php');
    ?>

    now we need our tree. rather than writing one chunk of code at a time and then attempting to explain it, i'm just going to heavily comment my code and use simple variable names so you can follow along with what each step is doing. most of this should be pretty straight forward and obvious, but i'll attempt to explain things in more depth where i feel is necessary. here is our directory function:

    <?php
    // get directory tree
    function directory($dir)
    {
        
    $mydir opendir($dir);
        while(
    false !== ($file readdir($mydir)))
        {
        if(
    $file != "." &amp;&amp$file != "..")
        {
            
    // we use $dir here rather than $mydir, because opendir() only returns a
            // resource, we need the actual path in order to get the expected result.
            // if our file is a directory, we need to search that directory
            
    if(is_dir($dir.$file))
            {
            
    // beware of safe mode when using chdir
            // it may generate warnings so we'll supress them with @
                
    @chdir('.');
            
    // by having the function call itself, it is now recursive
            // all sub directories will have an index of their own name
            
    $tree[$file] = directory($dir.$file.'/');
            @
    chdir('..');
            }
            else
            {
            
    $size getimagesize($dir.$file);
            
    // if our file matches the valid MIME types, we add it to
            // the array with a numeric index
            
    if(in_array($size['mime'], unserialize(TYPE)))
                
    $tree[] = $file;
            }
        }
        }
        
    closedir($mydir);
        return 
    $tree;
    }
    $tree directory(PATH);
    ?>

    we now have an array of our entire directory structure. we can easily tell the difference between which elements are directories and which elements are images by looking at the index. the next step is to figure out how to determine what is being requested. we can accomplish this by passing a variable along in the uri which we'll call $nav, the value of $nav will change dynamically depending on what the user has clicked.

    rather than traversing our entire array with every request, it would be much nicer if we could immediately jump directly to what the user wants. in this case, the value of $nav should be a list of elements which point to a particular location of our array. for example, let's assume we have the following tree structure:

    Array
    (
        [category one] =&gt; Array
        (
            [0] =&gt; img1.jpg
            [1] =&gt; img2.jpg
            [2] =&gt; img3.jpg
        )
        [category two] =&gt; Array
        (
            [sub category] =&gt; Array
            (
                [0] =&gt; img4.jpg
                [1] =&gt; img5.jpg
            )
        )
    )

    if we want to display img4.jpg, then the value of $nav should be ['category two']['sub category'][0]. if we want to display the gallery for the first category, then the value of $nav should be ['category one']. this way, we can take the value of $nav and call it within our $tree in order to get exactly what we want. when we create the hyperlinks for navigating the gallery later, they will give a new value to nav with each click that will look something like this: images.php?nav=>category+two>sub+category>0 - this way we'll always know exactly where we are. one thing to note is that i tend to use the ternary "?" operator a lot, if you're unfamiliar with this operator here is a quick visual explanation:

    <?php
    $value 
    = (some expression) ? 'value if true' 'value if false';
    ?>

    back to the project:

    <?php
    // let's grab our navigation
    $nav = isset($_REQUEST['nav']) ? urldecode($_REQUEST['nav']) : null;
    if(isset(
    $nav))
    {
        
    // we need to get rid of our location separators
        
    $crunch explode('&gt;'trim($nav));
        foreach(
    $crunch as $value)
        {
           
    // IMPORTANT! validate for teh h4x0rz
        
    if(!ctype_alnum(str_replace(' '''$value)))
            
    $invalid true;
        }
        if(
    $invalid)
        
    $nav null;
    }
    ?>

    since we're working with $_REQUEST values, it is important to make sure that the data we're receiving is the actual type of data that we expect. you can't guarantee that a user won't try and modify the path themself, but you can guarantee that only alpha-numeric characters will be accepted; we'll validate further as we go along. now that we have our path, we need to append it to our $tree array and direct our script where to go next.

    <?php
    // navigating the appropriate categories
    function categories($navtree)
    {
        
    // if we have a path to work with..
        
    if(isset($GLOBALS['nav']))
        {
        
    // we need to attach the path to our array
        // start counting from 1, as 0 will be empty
        
    for($i=1$i&lt;count($GLOBALS['crunch']); $i++)
            
    $navtree = &amp;$navtree[$GLOBALS['crunch'][$i]];

        
    // we'll study this function in a minute
        
    display_body($navtree);
        }
        else
        
    display_body($navtree);
    }
    categories($tree);
    ?>

    we know that if $nav is set, then so is $crunch, so we'll save ourselves the trouble of repeating code here by calling it globally. notice how we attach the path to our array by using a reference, trying to accomplish this with $array.$elements will not work as expected. i have to give a big thanks to zombie for helping me with that one.

    the next thing to consider is our display_body function, which will be the longest of all of our functions. this function needs to determin if we're requesting a single image, a listing of categories, or a gallery of thumbnails along with which page of the gallery we're looking at. but before we get into that, we need to setup the appropriate variables for our multiple pages of galleries. we can accomplish this by adding an additional variable to our uri path called $pg in much the same way we did with $nav. the value of $pg will either be a number, indicating what page we're on, or it will have the value "all" which will suggest that the user wants to view all of the images in a given gallery at the same time.

    <?php
    // decide what page of a paticular gallery we're viewing
    $pg = isset($_REQUEST['pg']) &amp;&amp; (ctype_digit($_REQUEST['pg']) || $_REQUEST['pg'] == 'all') ? $_REQUEST['pg'] : 0;
    $viewall is_numeric($pg) ? null true;
    $pg intval($pg) &lt;= $pg;
    ?>

    here we made sure that $pg will always have a numeric value, in order to avoid mathmatic problems in the following code. if the value of page is "all" we'll just define the variable $viewall as true and then convert $pg back to a number.

    <?php
    // images to display per page
    $section ROWS COLS;
    // last possible ending point for images, depending which page we're on
    $end $section $pg;
    // starting point for images, depending which page we're on
    $start $end $section;
    // previous page
    $prev $pg 1;
    // next page
    $next $pg 1;
    ?>

    now we can draw previous and next links. the variable passed, $total, will be the amount of images that we're working with.

    <?php
    // navigation (yes, cleverly named after the movie)
    function navigator($total)
    {
        
    // make a previous link
        
    $p '&lt;a href="'.$_SERVER['PHP_SELF']
           .
    '?nav='.rawurlencode($GLOBALS['nav'])
           .
    '&amp;pg='.$GLOBALS['prev'].'"&gt;&lt;&lt;&lt;/a&gt;';
        
    // make a next link
        
    $n '&lt;a href="'.$_SERVER['PHP_SELF']
           .
    '?nav='.rawurlencode($GLOBALS['nav'])
           .
    '&amp;pg='.$GLOBALS['next'].'"&gt;&gt;&gt;&lt;/a&gt;';
        
    // make a view all link
        
    $a '&lt;a href="'.$_SERVER['PHP_SELF']
           .
    '?nav='.rawurlencode($GLOBALS['nav'])
           .
    '&amp;pg=all"&gt;view all&lt;/a&gt;';
        
        
    // the navigation
        
    print('&lt;tr&gt;&lt;td align="center" colspan="' COLS '"&gt;');
        
        if((
    $GLOBALS['pg'] == &amp;&amp$GLOBALS['end'] &gt;= $total) || isset($GLOBALS['viewall']))
        print(
    '&lt;&lt; : view all : &gt;&gt;');
        elseif(
    $GLOBALS['pg'] == 1)
        print(
    '&lt;&lt; : '.$a.' : '.$n);
        elseif(
    $GLOBALS['end'] &lt$total)
        print(
    $p.' : '.$a.' : '.$n);
        else
        print(
    $p.' : '.$a.' : &gt;&gt;');
        
        print(
    '&lt;/td&gt;&lt;/tr&gt;');
    }
    ?>

    the navigator function just does some math to determine which links are appropriate to display depending on how many pages of images we have. we put this in a function in the case that we want our navigational links to appear in more than one place, such as above & below the galleries. now onto the juicy stuff:

    <?php
    // display category links and images
    function display_body($navtree)
    {
        if(isset(
    $GLOBALS['nav']))
        {
        
    // we'll need the path as a directory for displaying images
        
    for($i=1$i&lt;count($GLOBALS['crunch']); $i++)
            
    $uri .= !is_numeric($GLOBALS['crunch'][$i]) ? $GLOBALS['crunch'][$i].'/' '';
        }

        
    // if we have an array, then we are either requesting
        // category links or a gallery of images
        
    if(is_array($navtree))
        {
        
    // here we combine all the keys of our array into a string
        // if it does not have a numeric value then we must have
        // categories to display
        
    if(!is_numeric(implode(''array_keys($navtree))))
        {
            print(
    '&lt;tr&gt;&lt;td&gt;');
            foreach(
    $navtree as $key=&gt;$value)
            {
            if(!
    is_int($key))
            {
                
    // if our category value is an array, then
                // we create a link back to the images script and
                // give $nav the appropriate value
                
    if(is_array($value))
                print(
    '&lt;a href="'.$_SERVER['PHP_SELF']
                      .
    '?nav='.rawurlencode($GLOBALS['nav']
                      .
    '&gt;'.$key).'"&gt;'.$key.'&lt;/a&gt;&lt;br /&gt;');
                else 
    // empty category, no need to link it
                
    print($key.'&lt;br /&gt;');
            }
            }
            print(
    '&lt;/td&gt;&lt;/tr&gt;');
        }
        else
        {
            
    // if we're not working with categories, then we're
            // working with images, so let's decide how many
            // rows to display (depending if $viewall is true/false)
            
    $total count($navtree);
            if(isset(
    $GLOBALS['viewall']))
            {
            
    // math, gotta love it
            
    $check $total COLS;
            
    $rows is_int($check) ? $check floor($check) + 1;
            }
            else
            
    $rows ROWS;

            
    // display our navigation
            
    navigator($total);
            
    // start printing the table contents
            
    for($i=0$i&lt;$rows$i++)
            {
            print(
    '&lt;tr&gt;');
            for(
    $n=0$n&lt;COLS$n++)
            {
                
    $index $GLOBALS['start']++;
                
    // we either want the filename of the image, or
                // an empty space to fill the rest of the table
                
    $image $index &lt$total $navtree[$index] : '&amp;nbsp;';
                print(
    '&lt;td align="center" width="'.THMBWIDTH.'" height="'.THMBHEIGHT.'"&gt;');
                if(
    $image != '&amp;nbsp;')
                {
                
    // this link provides the exact path to the
                // image we want to display
                
    print('&lt;a href="'.$_SERVER['PHP_SELF']
                      .
    '?nav='.rawurlencode($GLOBALS['nav']
                      .
    '&gt;'.$index).'"&gt;');

                
    // the img tag is making the call to our next
                // script, imgsrc.php, which is being called
                // with the full directory path to the image
                
    print('&lt;img src="imgsrc.php?src='.PATH.rawurlencode($uri).$image.'" border="0" /&gt;');
                print(
    '&lt;/a&gt;');
                }
                else 
    // if no image, print a space
                
    print($image);
                
                print(
    '&lt;/td&gt;');
            }
            print(
    '&lt;/tr&gt;');
            }
            
    // display another navigation
            
    navigator($total);
        }
        }
        elseif(
    file_exists(PATH.$uri.$navtree))
        {
        
    // if $navtree is not an array, then we must be calling an
        // image directly, first we check if the file exists just
        // to make sure. now we get the appropriate path for
        // displaying the image
        
    $root explode('/'dirname(PATH.'.'));
        print(
    '&lt;tr&gt;&lt;td&gt;&lt;img src="'.end($root).'/'.$uri.$navtree.'"&gt;&lt;/td&gt;&lt;/tr&gt;');
        }
        else 
    // no array + no file = invalid
        
    print('&lt;tr&gt;&lt;td&gt;invalid request&lt;/td&gt;&lt;/tr&gt;');
    }
    ?>

    if you study the code well enough, the whole script should start to make sense, especially where we create our links and assign $nav the appropriate value to follow along with where we are surfing. as you've also probably noticed throughout this section, we always encode the data before being sent, and decode the data when it is being requested. we have used a lot of PHP's built in functions, if you want to know more about any of them just head on over to www.php.net/the_function_name_you_want_to_know_about

    the last script we need to work on is imgsrc.php, which will draw our thumbnails based on the path that it is sent via the variable $src as we just saw in our display_body function. before we move onto this script, i'd like to review what we've covered so far and show you how the images.php code should be organized as a whole.

    More Miscellaneous Articles
    More By notepad


       · if your larger images are dead, and you right-click to see the properties of the...
       · ... or#4 - You may not have the gd library properly installed or PHP compiled...
       · At first I was confused as to why TYPE was serialized in config.php only to be...
       · right, it actually says in the tutorial &quot;we'll define an array of valid...
       · *blush* I guess I should have &quot;thoroughly&quot; read through the text...
       · thanks this will help me make my gallery, i already started but this will help me...
       · as i add improvements to this gallery over time, i'll make them available...
       · new bug found that might be causing dead thumbnails.. if the names are odd,...
       · i dunno why i bothered to post that, considering i fixed it, and the post before...
       · Thank you for this great tutorial, it helped my understanding a lot!
       · Thank you for this great tutorial, it helped my understanding a lot!
       · Thank you for this great tutorial, it helped my understanding a lot!
       · alright the old update site has been shutdown. further updates for this gallery...
       · I found that i can't login to this admin panel. The rest of the script works, apart...
       · within your config file, make sure the HOST value is your domain. otherwise it will...
       · if you haven't gotten the updated script from the code library, definately do...
       · Make the thumbs pop up in new window? Some images viewed in full size torture my my...
       · Great tutorial.I am somewhat new to PHP. I managed to get the script working no...
       · Great tutorial.I am somewhat new to PHP. I managed to get the script working no...
       · Hi, im kinda new in PHP, and here is my (must be simple) problem: I putted the hole...
       · so i started over, from scratch. a revised tutorial will be published in phparch.com...
       · adding the revised code to the code section, again. the &quot;new...
       · 
       · error in line &quot;$size = getimagesize($dir.$file);&quot; of...
       · error in line &quot;$size = getimagesize($dir.$file);&quot; of...
       · 
       · 
     

    MISCELLANEOUS ARTICLES

    - Using PHP to Stream MP3 Files and Prevent Il...
    - 10 Must Have Firefox Improvements
    - All About OpenOffice 3.0
    - Shell Script Writing
    - Loops in the UNIX Shell
    - The Test in the UNIX Shell
    - Data Streams and the UNIX Shell
    - Control Mechanisms of the UNIX Shell
    - Variables Within the UNIX Shell
    - The Shell and UNIX
    - In Detail: UNIX File Systems
    - Rights Management in UNIX
    - UNIX File Systems
    - The Terminal in UNIX
    - Operating Systems and UNIX





    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 2 Hosted by Hostway
    Stay green...Green IT