Previous or Next? Paginating Records with PHP, part 1

Putting all of your content for a particular file on one page can be very user unfriendly to website visitors. Nobody likes to be confronted by a tiny vertical scroll bar! In this article, the first in a series, you will learn a simple way to paginate records from a text file using PHP.

Introduction

We see it every day, when surfing the Web looking for new content to expand our background as Web developers. More and more websites offer vast amounts of fresh information to satisfy users and keep them coming back for more. Most of the time, data is stored in databases and displayed according to user requests, in a fairly decent way, sticking more or less to the principles of readability. So, what’s wrong about it?

If we take a look at some popular professional websites, we immediately notice that they offer some kind of paginating mechanism to display database records. From simple “previous” and “next” navigational links, to more complex numerated links, the range is quite wide. Let’s take the case of Google, for showing an excellent example of a sophisticated and efficient paginating system. Fine, let’s admit it. Here, we’re talking about the big boys who most of the time (but certainly not always) do know what approach to take when dealing with record paging.

But, what about the others? Don’t tell me that you never had to suffer that annoying experience of finding a website that happily loads its content, while you’re watching with a feeling of growing panic as the vertical scroll bar control gets tinier and tinier! Oh, is that a severe punishment, or what?

But let’s stop being ironic and face the problem that we have here. Showing elegant, paginated information gives our sites a very polished look, and certainly is a great way to enhance readability for visitors. Thus, the subject is relevant enough to be seriously considered. That’s where this article comes in. We’re going to present different approaches for implementing an efficient paginating mechanism using PHP, which hopefully will be useful to employ on any existing or future Web projects. So, let’s jump to the next section to find out more.

{mospagebreak title=The first step: paginating records in a procedural way}

Our first method for paginating records might be easily developed by taking a procedural approach: using a flat text file as the data source for displaying information, and defining a PHP function that takes care of paginating the records. Sounds like something good to deploy, at least for the initial step, right?

Let’s begin defining a simple text file, which contains several lines (our records), including information about a song’s author and the song’s title. The example file, which is called “data.dat,” could be structured as listed below:

Chariots of fire|Vangelis

Friends of Mr. Cairo|Vangelis

Lucifer|The Alan Parson Project

The eye in the sky|Alan Parson Project

Caribean Blue|Enya

Only Time|Enya

Music|John Miles

The turn of a friendly card|The Alan Parson Project

Children|Robert Miles

One and One|Robert Miles

Sadness|Enigma

Mea Culpa|Enigma

Cherry Blossom Girl|Air

Hot stuff|Donna Summer

Bad Girls|Donna Summer

I will survive|Gloria Gaynor

Rimes and reasons|John Denver

Touch and go|Emerson,Lake and Powell

In Jeopardy|Roger Hogdson

Ameno|Era

As you can see, our text file containing information about several songs has been created, defining two fields for each line, author and title respectively, separated by a pipe (“|”) character. This way we’ve established the overall structure for this simple flat database. Please don’t start complaining about my musical preferences, because they’re beyond the scope of this article. Let’s focus our attention on the code listed above.

Once we have defined the data source file, we need to create a PHP function for retrieving the records from the file, and generating the corresponding paginating links. In fact, the process is pretty straightforward, as we’ll see in a moment. Now, let’s start writing the function to paginate records. I’ve named it “paginateRecords()”, and its definition is the following:

function paginateRecords($dataFile,$page,$numRecs=5){

$output=”;

// validate data file

(file_exists($dataFile))?$data=array_reverse(file
($dataFile)):die(‘Data file not valid.’);

// validate number of records per page

(is_int($numRecs)&&$numRecs>0)?$numRecs=$numRecs:die
(‘Invalid number of records ‘.$numRecs);

// calculate total of records

$numPages=ceil(count($data)/$numRecs);

// validate page pointer

if(!preg_match(“/^d{1,2}$/”,$page)
||$page<1||$page>$numPages){

$page=1;

}

// retrieve records from flat file

$data=array_slice($data,($page-1)*$numRecs,$numRecs);

// append records to output

foreach($data as $row){

$columns=explode(‘|’,$row);

foreach($columns as $column){

$output.=$column.’&nbsp;';

}

$output.='<br />';

}

// create previous link

if($page>1){

$output.='<a href=”‘.$_SERVER['PHP_SELF'].’?page=’.
($page-1).'”>&lt;&lt;Previous</a>&nbsp;';

}

// create intermediate links

for($i=1;$i<=$numPages;$i++){

($i!=$page)?$output.='<a href=”‘.$_SERVER
['PHP_SELF'].’?page=’.$i.'”>’.$i.'</a>&nbsp;':$output.=$i.’&nbsp;';

}

// create next link

if($page<$numPages){

$output.=’&nbsp;<a href=”‘.$_SERVER['PHP_SELF'].’?
page=’.($page+1).'”>Next&gt;&gt;</a> ‘;

}

// return final output

return $output;

}

Don’t feel intimidated by the function’s source code, since it’s really easy to understand. In order to grasp the underlying logic, let’s break down the code to have a detailed look at each section. Are you ready? Let’s go for it.

{mospagebreak title=A deeper look at the “paginatetRecords()” function}

First, the function accepts three parameters, in the following order: the text file from which we’re retrieving data, the page pointer that indicates the current page to be viewed, and finally the number of records per page to be displayed, according to our paginating criteria. In this case, I’ve assigned a default value of 5, so the total records should be displayed in chunks of five at once, and then provide the proper paginating links.

Still with me? Okay, now the function initializes the $output variable that will store the formatted records and the links to be displayed in the browser. The next step involves validating each of the parameters passed to the function. First, the function checks whether there is a valid data source text file. If it exists, then the file is read in reverse order, assuming that the most recent entry in our song file is the last line of the file. Otherwise, if no data file is found, the function stops the execution by calling a die() statement.

The next parameter to be validated is the number of records per page. If this value is a positive integer, it’s assigned to the $numRecs variable. Otherwise, the function kills the script with a call to die(). Nothing unexpected, right?

Finally, the function calculates the number of pages needed to display all of the records, dividing the total of records by the number of records per page. Remember, it’s simple mathematics. Once this value has been calculated, we need to validate the $page variable, for avoiding having it tampered with directly from the query string — just in case someone with malicious thoughts tries to make the script crash or to inject improper code straight into the function. The ancient principle is always present: trust no one!

The process for validating the function parameters is done with the following lines:

// validate data file

(file_exists($dataFile))?$data=array_reverse(file
($dataFile)):die(‘Data file not valid.’);

// validate number of records per page

(is_int($numRecs)&&$numRecs>0)?$numRecs=$numRecs:die
(‘Invalid number of records ‘.$numRecs);

// calculate total of records

$numPages=ceil(count($data)/$numRecs);

// validate page pointer

if(!preg_match(“/^d{1,2}$/”,$page)
||$page<1||$page>$numPages){

$page=1;

}

By this point, the function has validated its parameters, and it’s ready to get the records from the data file. Since data is now stored in the $data array, the task of retrieving the records according to the current page is quite simple. Using the handy “array_slice()” PHP built-in function to move the internal array pointer to the desired place and get a specific number of elements, makes it really simple obtain the corresponding records. That’s what we do with the expression:

$data=array_slice($data,($page-1)*$numRecs,$numRecs);

As you can see, if we’re at the first page ($page=1), the first five array elements are obtained. In a similar way, for the second page ($page=2), the second set of five elements is retrieved, and so on. This simple expression is very powerful, since it is allowing us to navigate trough the array structure with no big hassles.

Now that the function has stored the corresponding records, all that it needs to do is loop over them to get the proper values. First we iterate over each line of the $data array (considered as a row), and next over the columns (or fields) of that element. Remember that we’ve defined our data file with two columns separated by a pipe character, so we explode each line into columns. The process ends up applying some basic formatting to the values and adding them to the $output variable, but this might be easily changed to define a more polished look. The loop process is performed with the lines:

// append records to output

foreach($data as $row){

$columns=explode(‘|’,$row);

foreach($columns as $column){

$output.=$column.’&nbsp;';

}

$output.='<br />';

}

Happily, our required records are stored in the $output variable. Half of the job is already done. We need to create the paging links to make the script fully functional. In order to build the links, the function checks whether it’s possible to generate a <previous> link, in the following manner:

// create previous link

if($page>1){

$output.='<a href=”‘.$_SERVER['PHP_SELF'].’?page=’.
($page-1).'”>&lt;&lt;Previous</a>&nbsp;';

}

If the page pointer is greater than 1, it means that we’re not on the first page, so we append a previous link to the final output. With our previous link generated, we need to look at the intermediate links, which are created with this simple loop:

for($i=1;$i<=$numPages;$i++){

($i!=$page)?$output.='<a href=”‘.$_SERVER
['PHP_SELF'].’?page=’.$i.'”>’.$i.'</a>&nbsp;':$output.=$i.’&nbsp;';

}

Please notice that the snippet displays the page numbers, appending the $page variable to each link created with the $_SERVER['PHP_SELF'] predefined variable, and doesn’t generate any link when it detects the current page.

The final step consists of creating the <next> link, whenever possible. If the page pointer is less than the number of pages, the next link is appended to the final output. The function creates this link with the lines:

// create next link

if($page<$numPages){

$output.=’&nbsp;<a href=”‘.$_SERVER['PHP_SELF'].’?
page=’.($page+1).'”>Next&gt;&gt;</a> ‘;

}

Good! We’re retrieving a specified number of records and creating those desired page links. With a few lines of code, we can offer that functionality on our site to pleased users. Indeed, we’re headed in the right direction. But, let’s no waste more time congratulating ourselves, and put this function into action.

{mospagebreak title=Putting the “paginateRecords()” function into action: procedural record paging}

Let’s jump straight in and test out our recently developed “paginateRecords()” function. With three lines of code, we’re ready to paginate records on our Web pages. Here’s a possible regular implementation:

<html>

<head>

<title>PAGINATING DATA WITH PHP</title>

<meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1″ />

</head>

<body>

<p>Record Listing</p>

<?php

require_once(‘pager.php’);

$page=$_GET['page'];

echo paginateRecords(‘data.dat’,$page);

?>

</body>

</html>

Let’s be honest. The required code to make record paging is extremely short and understandable. We’ve just included the file that contains the function and invoked it, passing in the parameters the data file to be read and the page pointer to display the records. Just give it a try and add your own improvements. Simple and straightforward, isn’t it?

However, there are some issues to be considered about this approach.  This solution might be suitabel for small websites, where you can live quite happily delivering content from simple text files. With larger applications, however, and with heavy loads and more demanding requirements, this approach falls short. What’s more, we’re mixing HTML markup with PHP code, which is not recommended at all.

So, can we do it any better? You bet. We must improve this technique by developing a solution definitely more portable for larger websites, and able to deal with a relational database system such as MySQL. That will be our next step in the paging record process.

Summarizing and further improvements

In this first part, we looked at a simple PHP function for paginating records extracted from a flat text file. Also, we saw how simply it can be implemented, with just a few lines of code. Of course, this procedural method supports many possible improvements, being a handy introduction to paging techniques. If you’re already working with Web applications that require recordset paging very frequently with minor headaches, just take the function and play with it to meet your needs.

In the coming second part, we’ll look at a mature OOP approach, defining a PHP class to efficiently handle recordset paging processes, considerably more suitable for larger applications. It sounds very promising. We have the tools and the knowledge for developing such a class. So, get ready for the next part, and stay tuned!

[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort