Tiffany B. Brown

Simple pagination for arrays with PHP 5

While working on a recent project, I had to build a feature that displayed a list of files available in a directory. A simple way is just to use scandir() and a foreach loop to spit out a pretty list.

There’s a small problem though: long lists aren’t all that user friendly. I decided instead to paginate the results. Here’s one way to do it using PHP 5:

Step 1: Read the directory


/*

 * scandir is only available in PHP 5 or higher.

 * It returns an array of ALL available files in the 

 * specified directory 

*/



$allfiles = scandir('/directory/to/scan/');    

Now we don’t want to display every file. Some files are system files. Some files may not be the right format. Here, we’re going to eliminate any file name that starts with a period.


# intialize a new array of files that we want to show

$goodfiles = array();

		

# add a file to the $goodfiles array if its name doesn't begin with a period

foreach($allfiles as $f){

	if(strpos($f,'.')!==0){

		array_push($goodfiles,$f);

	}

}

Step 2: Split it! Split it good!

Now we get to the heart of things: determining how many pages there will be and how many items we’ll show per page. It’s remarkably simple thanks to PHP’s array_chunk() function. The array_chunk function takes two parameters: the array that you want to split, and the number of units that should be in each set.

$pages = array_chunk($goodfiles, 5);

This produces a multidimensional array which, if we print_r it, looks a bit like this (let’s assume we have 13 files in the directory).


Array

(

    [0] => Array

        (

            [0] => About_RFSB06WEB.flv

            [1] => Kids_Excited.flv

            [2] => Kids_Start_Run.flv

            [3] => Kids_start.jpg

            [4] => Kids_start_sm.jpg

        )



    [1] => Array

        (

            [0] => image01.jpg

            [1] => image02.jpg

            [2] => image03.jpg

            [3] => image04.jpg

            [4] => image05.jpg        

        )



    [2] => Array

        (

            [0] => image06.jpg

            [1] => image07.jpg

            [2] => image08.jpg

        )

)

Each parent array is a page. Each child array is the content for that page. Now we just have to specify which page we want to view. In this example, we’re going to pass the desired page to the script as part of a query string — showfiles.php?showpage=1.

Step 3: Linking up

So now that our array is all split and chunked, we can build our page links. As I explained earlier, using array_chunk() creates our ‘pages.’ To build our pagination navigation, then, we just need to create as many links as there are pages. Let’s do this with a for loop.


<? for($i=1; $i< count($pages)+1; $i++): ?>

     <a href="showfiles.php?showpage=<? echo $i;?>"<<? echo $i; ?></a>

<? endfor; ?>

Remember that we're doing a page count, so we want to start at one (not zero). Now it's just a matter of grabbing the variable's value to specify which array to show. We're grabbing that value from the query string in the URL.


$pgkey = (int)$_GET['showpage']; // forces $_GET['showpage'] to be an integer

$pages[$pgkey]; 

If you want to highlight which page the user is on, add if / else logic to check whether the value of $i is the same as the value of $_GET['showpage'] and apply a style or CSS class name.

Step 4: Showing the files

The final step is to show the files on each page. Simply use a foreach loop.

foreach($pages[$pgkey] as $file){ echo $file.'<br />'; }

This is a technique that you could conceivably use to display any array data across pages.

39 Responses to “Simple pagination for arrays with PHP 5”

  1. Steve W says:

    Neat script, it took me a bit to put together that this is all on one page. I wasn’t aware of the scandir function in PHP 5. Much simpler then the opendir/readdir combination of previous version. Great tip!

    It’s conceivable that between page loads a file could be added or subtracted, which would change the chunked array values.

    A tweak to consider is not nesting the count(array) in the for loop. Set the count in a variable, and then use the variable. With the nested count, it has to be computed every time the loop iterates. However, the value is static, so the extra (however minuscule) processing isn’t needed.
    (The closing bracket for the tag is backwards in the example as well..)

    <?
    $cntArrPages = count($pages)+1;
    for($i=1; $i
    <a href="showfiles.php?showpage=">

  2. Steve W says:

    Neat script, it took me a bit to put together that this is all on one page. I wasn’t aware of the scandir function in PHP 5. Much simpler then the opendir/readdir combination of previous version. Great tip!

    It’s conceivable that between page loads a file could be added or subtracted, which would change the chunked array values.

    A tweak to consider is not nesting the count(array) in the for loop. Set the count in a variable, and then use the variable. With the nested count, it has to be computed every time the loop iterates. However, the value is static, so the extra (however minuscule) processing isn’t needed.
    (The closing bracket for the tag is backwards in the example as well..)

    <?
    $cntArrPages = count($pages)+1;
    for($i=1; $i
    <a href="showfiles.php?showpage=">

  3. Steve W says:

    hrrm… the <code> didn’t do what I expected..

    Trying it without that to see if it will show up in the comments.

    <?
    $cntArrPages = count($pages)+1;
    for($i=1; $i
    <a href=”showfiles.php?showpage=”>

  4. Steve W says:

    hrrm… the <code> didn’t do what I expected..

    Trying it without that to see if it will show up in the comments.

    <?
    $cntArrPages = count($pages)+1;
    for($i=1; $i
    <a href=”showfiles.php?showpage=”>

  5. Steve W says:

    Last try, doing a replace on the brackets…

    <?
    $cntArrPages = count($pages)+1;
    for($i=1; $i<$cntArrPages ; $i++): ?>
    <a href=”showfiles.php?showpage=<? echo $i;?>”><? echo $i; ?></a>
    <? endfor; ?>

  6. Steve W says:

    Last try, doing a replace on the brackets…

    <?
    $cntArrPages = count($pages)+1;
    for($i=1; $i<$cntArrPages ; $i++): ?>
    <a href=”showfiles.php?showpage=<? echo $i;?>”><? echo $i; ?></a>
    <? endfor; ?>

  7. Very smoov. I never bothered to read the doc’s on array_chunk—I just would catch a glimpse of “chunk” on my way to something else…

  8. Very smoov. I never bothered to read the doc’s on array_chunk—I just would catch a glimpse of “chunk” on my way to something else…

  9. EMS says:

    nice example.

  10. EMS says:

    nice example.

  11. slash news says:

    nice one, saved me some time.

  12. slash news says:

    nice one, saved me some time.

  13. Karry says:

    Perfect! I have been searching for this for an hour! You have saved me some time!

  14. Karry says:

    Perfect! I have been searching for this for an hour! You have saved me some time!

  15. Hussain says:

    $myarray = (1, 2, 3);
    $len = count( $myarray ) ; // len = 3
    ie.
    $len[0] = 1
    $len[1] = 2
    $len[2] = 3

    so in Step 4:
    change the for loop to have PGKEY-1
    foreach($pages[$pgkey-1] as $file){ echo $file.''; }

  16. Hussain says:

    $myarray = (1, 2, 3);
    $len = count( $myarray ) ; // len = 3
    ie.
    $len[0] = 1
    $len[1] = 2
    $len[2] = 3

    so in Step 4:
    change the for loop to have PGKEY-1
    foreach($pages[$pgkey-1] as $file){ echo $file.'
    '; }

  17. Hussain, your example assumes that we know how many pages we'll have. The idea is that you would be able to run this script and it would create pages for you regardless of how many files are actually on the server.

  18. Hussain, your example assumes that we know how many pages we'll have. The idea is that you would be able to run this script and it would create pages for you regardless of how many files are actually on the server.

  19. Hussain says:

    Hello again Tiffany
    that example was only to explain why the index must be PGKEY-1, since you are showing the page count starting by 1.

    try navigating the links ( especially the last page ) , you will get ( Invalid argument supplied for foreach() ).

    commit that change i mentioned and navigate again…. problem solved, no error.

    php is like C language, the index starts counting 0,1,2,etc..
    actually, i should not use that example because you have in step #2
    the print_r() output showing each array index starting at 0.

    ;o)

  20. Hussain says:

    Hello again Tiffany
    that example was only to explain why the index must be PGKEY-1, since you are showing the page count starting by 1.

    try navigating the links ( especially the last page ) , you will get ( Invalid argument supplied for foreach() ).

    commit that change i mentioned and navigate again…. problem solved, no error.

    php is like C language, the index starts counting 0,1,2,etc..
    actually, i should not use that example because you have in step #2
    the print_r() output showing each array index starting at 0.

    ;o)

  21. katyayani says:

    <?php
    $sates=array("Andhra Pradesh"=>"AP","Arunachal

    Pradesh"=>"ArP");
    echo'<select name="states" >';
    foreach($states as $key=> $value)
    {
    echo'<option name=$key >$value</option>n';
    }

    This will not options oparation.plz reply quickly
    ?>

  22. katyayani says:

    <?php
    $sates=array("Andhra Pradesh"=>"AP","Arunachal

    Pradesh"=>"ArP");
    echo'<select name="states" >';
    foreach($states as $key=> $value)
    {
    echo'<option name=$key >$value</option>n';
    }

    This will not options oparation.plz reply quickly
    ?>

  23. chris says:

    excellent tutorial, clearly explained and very useful – thanks for posting.

  24. chris says:

    excellent tutorial, clearly explained and very useful – thanks for posting.

  25. Leslie P. says:

    I’ve been having problems subscribing to this feed. It lets me subscribe and it loads in the rss reader program I use (which is netnewswire for mac) but it’s not showing new posts. A few duplicates too. Am I using the wrong url perhaps?

  26. Leslie P. says:

    I’ve been having problems subscribing to this feed. It lets me subscribe and it loads in the rss reader program I use (which is netnewswire for mac) but it’s not showing new posts. A few duplicates too. Am I using the wrong url perhaps?

  27. Al Toman says:

    Hello Tiffany,
    The statement for($i=1; $i< count($pages)+1; $i++): fails for me. I have 7 files in the test directory set at 5 per page. It brings up pages [1] and [2]. Clicking on [1] shows files 6 -7 and clicking on [2] results in an error statement.

    However, if I modify the statement to for($i=0; $i< count($pages); $i++): it brings up pages [0] and [1]. Clicking on [0] shows the first 5 files and clicking on [1] shows the next 2 files out of the seven.

    The later works very nicely.

    What may I be doing wrong!?!

    Thanks,
    Al

  28. Al Toman says:

    Hello Tiffany,
    The statement for($i=1; $i< count($pages)+1; $i++): fails for me. I have 7 files in the test directory set at 5 per page. It brings up pages [1] and [2]. Clicking on [1] shows files 6 -7 and clicking on [2] results in an error statement.

    However, if I modify the statement to for($i=0; $i< count($pages); $i++): it brings up pages [0] and [1]. Clicking on [0] shows the first 5 files and clicking on [1] shows the next 2 files out of the seven.

    The later works very nicely.

    What may I be doing wrong!?!

    Thanks,
    Al

  29. tiffany says:

    hi al, what’s the error you’re getting?

    in any case, the important part is that the first page link reads ’1′ and not ’0,’ right? so instead, use your code and add +1 to $i when it is printed to the page.

  30. tiffany says:

    hi al, what’s the error you’re getting?

    in any case, the important part is that the first page link reads ’1′ and not ’0,’ right? so instead, use your code and add +1 to $i when it is printed to the page.

  31. Al Toman says:

    Yeah, that’s pretty much what I did after playing around a bit. I tested it out on a simple gallery I wanted: gallery

    I think it works cool, hey!?!

    The error I got before I modified the script is:
    Warning: Invalid argument supplied for foreach() in …

    Thanks for the tut!

  32. Al Toman says:

    Yeah, that’s pretty much what I did after playing around a bit. I tested it out on a simple gallery I wanted: gallery

    I think it works cool, hey!?!

    The error I got before I modified the script is:
    Warning: Invalid argument supplied for foreach() in …

    Thanks for the tut!

  33. Perfect! I was wondering if pagination would be possible without MySQL and only with an array with the contents of a directory. Saved me much time. Thanks so much!

  34. Perfect! I was wondering if pagination would be possible without MySQL and only with an array with the contents of a directory. Saved me much time. Thanks so much!

  35. Perfect! I was wondering if pagination would be possible without MySQL and only with an array with the contents of a directory. Saved me much time. Thanks so much!

    edit:

    Would there be a way to order them the opposite way? (like rsort) Can’t figure that one out…

  36. Perfect! I was wondering if pagination would be possible without MySQL and only with an array with the contents of a directory. Saved me much time. Thanks so much!

    edit:

    Would there be a way to order them the opposite way? (like rsort) Can’t figure that one out…

  37. Anonymous says:

    I wrote this tutorial for a beginner-intermediate PHP programmer. I wanted to keep the focus on the pagination code rather then on the database As many new PHP programmer still don’t use PDO or any other database abstraction layer, I felt it was necessary to keep the database part simple. Someone using PDO can easily adapt the above without much changes. By auto insurance company