custom pagination PHP class

Discussion in 'Web Design and Development' started by gotenks05, Jul 2, 2010.

  1. gotenks05 macrumors member

    Joined:
    Jan 1, 2009
    #1
    After many attempts in making my site PHP-based with some count being database-driven, I succeeded. Right now, I am trying to cut down the PHP script by moving things into separate functions and/or classes. So far, I have been able get one of the important things cut down to only two scripts, which is the MySQL connection info and selecting MySQL databases. However, I'm having troubles with pagination. It works right now, but the problem is that I need to go through each page that has pagination and make changes manually to the portion of PHP that performs the pagination. In order to simplify this, and cut down on editing my current PHP scripts too much, I decided to create my own pagination PHP class. There are two problems though. First, the MySQL query for total number of rows is not being accepted as an argument and PHP claims a warning of dividing by zero. Second, the offset and rowsperpage variables are causing problems with the main MySQL query, after implementing the class on a test run.

    the class source file looks like this:

    PHP:
    <?php
    /* this class makes it easier to paginate MySQL queries */
    class paginate
    {
        var 
    $rowsperpage// variable to hold desired number of rows
        
    var $totalpages// variable to hold total number of pages
        
    var $range// variable to control number of links in page navigation
        
    var $text// variable to control pages linked to
        
    var $offset// variable to declare offset
        
    var $currentpage 0// variable to house currentpage

        /* the following function performs the pagination by assigning the appropriate values to each variable*/
        
    public function paginate(&$numrows$row 4)
        {
            
    // set maximum rows per page
            
    $this->rowsperpage $rows;
            
    // get total pages
            
    $this->totalpages ceil($numrows/$this->rowsperpage);
            
    //get current page or set default
            
    if (isset($_GET['currentpage']) && is_numeric($_GET['currentpage']))
            {
                
    $this->currentpage = (int) $_GET['currentpage'];
            }
            else
            {
                
    $this->currentpage 1;
            }
            
    // make sure that the last page is really last
            
    if ($this->currentpage $this->totalpages)
            {
                
    $this->currentpage $this->totalpages;
            }
            else;
            
    // make sure there is no number less than 1
            
    if ($this->currentpage 1)
            {
                
    $this->currentpage 1;
            }
            else;
            
    //offset data
            
    $offset = ($this->currentpage -1) * $this>rowsperpage;
        } 
    // end function

        // the following function displays the page navigator
        
    public function counter(&$display$numlinks 1)
        {
            if (
    $currentpage || $currentpage == $totalpages)
            {
                
    // show back link
                
    echo('<a href="http://'$_SERVER['SERVER_NAME'] . '/?content=' $display '&currentpage=1"><<</a>' '  |  ');
                
    // create go back one page variable
                
    $prevpage $this->currentpage -1;
                
    // create link to previous page
                
    echo('<a href="http://'$_SERVER['SERVER_NAME'] . '/?content=' $display '&currentpage=' $prevpage '"><</a>' '  |  ');
            }
            else;
            
    // create range to limit link display
            
    $this->range $numlinks;

            for (
    $x = ($this->currentpage $this->range); $x < (($this->currentpage $this->range) +1); $x++)
            {
                if (
    $x && $x <= $totalpages)
                {
                    if(
    $x == $this->currentpage)
                    {
                        echo(
    "<b>$x</b>");
                    }
                    else
                    {
                        echo(
    '<a href="http://' $_SERVER['SERVER_NAME'] . '/?content=' $display '&currentpage=' $x '">' $x '</a>');
                    }
                } 
    // end if
            
    // end for loop 
            
    if($currentpage == || $currentpage && $currentpage != $totalpages)
            {
                
    // create go forward one page variable
                
    $nextpage $this->currentpage +1;
                
    // create link to next page
                
    echo('  |  ' '<a href="http://'$_SERVER['SERVER_NAME'] . '/?content=' $display '&currentpage=' $nextpage '">></a>' '  |  ');
                
    // show last page link
                
    echo('<a href="http://'$_SERVER['SERVER_NAME'] . '/?content=' $display '&currentpage=' $totalpages .'">>></a>');
            }
            else;
        } 
    // end function

        // this function displays the position of the query
        
    function position()
        {
            echo(
    '<br>You are on page ' $this->currentpage ' of ' $this->totalpages ' pages.');
        } 
    // end function

        // this function returns the rowsperpage
        
    function getrowsperpage()
        {
            return 
    $this->rowsperpage;
        } 
    // end function

        // this function returns the offset
        
    function getoffset()
        {
            return 
    $this->offset;
        } 
    // end function
    // end class
    the PHP script using the class looks like this:

    PHP:
    <?php
    $paginate 
    = new paginate();
    db_access("faq""read");
    $sql mysql_query('SELECT COUNT(*) FROM faq');
    $r mysql_fetch_array($sql);
    $totalrows $r[0]; // assign total rows to variable
    $paginate->paginate($totalrows10);
    $offset $paginate->getoffset();
    $rowsperpage $paginate->getrowsperpage();
    $sql1 mysql_query("SELECT question, answer FROM faq LIMIT $offset$rowsperpage");
    echo(
    '<ol>');
    while(
    $row mysql_fetch_array($sql1))
    {
        
    $question $row["question"];
        
    $answer $row["answer"];
        echo(
    "\n" '<li>
            <dl>
            <dt class="bold">' 
    .$question '</dt>
            <dd>' 
    $answer .'</dd>
              </li>'
    );
    }
    echo(
    "\n" '</ol>');
    $paginate->counter($content2);
    $paginate->position();
    ?>
    This PHP code is using the custom function I made to connect to MySQL and select a database quickly. There are two sets of log in info. One that logs in as a user with read/write access to the database and one that has read-only access to the database. "read" tell the function to login in as the read-only user, while "write" logins in as the other user.

    There is an HTML page that loads the previous code that looks like this:

    HTML:
    <div class="welcome"> <!-- this div element contains the message that introduces people to the content -->
    <p>Welcome to the FAQ portion of this website. On this page, people will questions that have been asked many times, common questions to expect, things that <name> has discovered on check runs, or things <name> expects, but does not want to deal with. If you can't find your answer here and the updates do not say that your problem has been resolved, Contact <name>.  He checks his E-mail just about every day, as long as he has an Internet connection.  State your browser, and Operating System, as well as page (if your problem is only on a single page).  <name> will usually get back to you within the same week you contact him, but do not be surprised if it takes longer.  For best results, wait at least one month before contacting him again, as he will definitely get to it before then.</p>
    </div> <!-- close the welcome div element -->
    <div class="main"> <!-- this div element holds the actual content for the page -->
    <h2>Frequently Asked Questions</h2>
    <?php include("faq_content.php"); ?>
    </div> <!-- close the main content div -->
    And finally, since it is obvious that the HTML is incomplete, here is the main PHP file used for test, which imports the previous HTML code:
    PHP:
    <?php
    include("db_access.php");
    include(
    "paginate.php");
    $content $_GET['content'];
    if(
    is_null($content))
    {
        
    $content "faq";
    }
    echo(
    '<html>');
    echo(
    '<head>');
    echo(
    '<title>');
    echo(
    'Test');
    echo(
    '</title>');
    echo(
    '</head>');
    echo(
    '<body>');
    include(
    $content '.html');
    echo(
    '</body>');
    echo(
    '</html>');
    ?>
     
  2. angelwatt Moderator emeritus

    angelwatt

    Joined:
    Aug 16, 2005
    Location:
    USA
    #2
    Try using mysql_num_rows for get the number of rows.

    I'd recommend printing out some of the variables to see if they're getting set as you think they are. Maybe write them to a log file.
     
  3. Cabbit macrumors 68020

    Cabbit

    Joined:
    Jan 30, 2006
    Location:
    Scotland
    #3
    Not looked though it all yet but firstly don't use "var" use public, private or protected. Var's direct replacement is public.
     
  4. gotenks05 thread starter macrumors member

    Joined:
    Jan 1, 2009
    #4
    I tried printing the offset and rowsperpage functions and nothing appear, so it looks like they did not get anything in the local variables. The mysql_num_rows suggestion did not work out too well, since I could only get it to work by making a separate variable with a query then load the query into the function you suggested, which was not much different than what was there before.

    Okay, I just changed them.
     
  5. Cabbit macrumors 68020

    Cabbit

    Joined:
    Jan 30, 2006
    Location:
    Scotland
    #5
    Try var_dump on the array your sending to the pagination class to see if the array is populated then do the same inside the class.
     
  6. gotenks05 thread starter macrumors member

    Joined:
    Jan 1, 2009
    #6
    Both times I got 11, which is what the count of MySQL records should come to, but PHP is complaining that argument 1 is missing. If it displays the correct count, why does the server think that think argument is not given?
     
  7. angelwatt Moderator emeritus

    angelwatt

    Joined:
    Aug 16, 2005
    Location:
    USA
    #7
    I just noticed this line,
    Code:
        public function paginate(&$numrows, [B][COLOR="Red"]$row[/COLOR][/B] = 4)
        {
            // set maximum rows per page
            $this->rowsperpage = [B][COLOR="Red"]$rows[/COLOR][/B];
    The function gets a variable of $row, no 's' on the end. That's why there's a divide by zero issue. You're using an undeclared variable.
     
  8. gotenks05 thread starter macrumors member

    Joined:
    Jan 1, 2009
    #8
    Thanks. That part helped. I still need help with this warning:

    The above quote was edited, in order to hide filesystem structure. Note: smiley's not supposed to be there, so it should be obvious what the warning says.

    I still have the other error that is from the offset and rowsperpage variables messing up the main SQL query.

    Update: With the of help angelwatt's post, I was able to print the output of the rowsperpage variable, but the offset still has nothing, which means that it is only the offset variable that is messing with the main SQL query right now.

    Update 2: I found a problem in my own code, so offset is now fixed. The warning just can't be fixed, so Is the a way for me to automatically have the function block it out, or do I need to add '@' myself?
     
  9. angelwatt Moderator emeritus

    angelwatt

    Joined:
    Aug 16, 2005
    Location:
    USA
    #9
    Have you tried &$numrows without the & in front? You aren't using that variable as a reference variable so I don't believe it's necessary for what you're doing.
     
  10. gotenks05 thread starter macrumors member

    Joined:
    Jan 1, 2009
    #10
    Yes, I tried it, but it did not help. I did find a way to hide the false warning, since the class was working otherwise, so the class is working now. thanks for the help.
     
  11. Cabbit macrumors 68020

    Cabbit

    Joined:
    Jan 30, 2006
    Location:
    Scotland
    #11
    This little snip will help you hide unwanted errors from public view but still record them in /logs/error.log. But ideally you want to find out why there is a warning. There is usually a reason for it.

    PHP:
    # Tells PHP to report all errors, not to be confused with displaying errors.
    error_reporting(E_ALL);

    # This one tells PHP to display errors. 1 is on, 0 is off.
    ini_set('display_errors'0);

    # This tells PHP we want to log errors.
    ini_set('log_errors'1);

    # Finally we tell PHP where we want to save these errors.
    ini_set("error_log"_SitePath "/logs/error.log");
     
  12. gotenks05 thread starter macrumors member

    Joined:
    Jan 1, 2009
    #12
    Thanks for the tip. That does sound more useful than what I did. I simply set error_reporting to "0" in my pagination class.

    Since, this post seems to be popular, here is the code that works. It is Database server independent, but you'll still need to edit the class file for it to work:

    PHP:
    <?php
    /* this class makes it easier to paginate MySQL queries */
    /* the following code, before the class declaration, was suggested by babyjenniferLB from Macrumors forums on July 3, 2010. I decided to leave her comments in as they describe what is going on */
    # Tells PHP to report all errors, not to be confused with displaying errors.
    error_reporting(E_ALL);

    # This one tells PHP to display errors. 1 is on, 0 is off.
    ini_set('display_errors'0);

    # This tells PHP we want to log errors.
    ini_set('log_errors'1);

    # Finally we tell PHP where we want to save these errors.
    ini_set("error_log""/home/bryce/Documents" "/logs/error.log");

    // declare class and enter code
    class paginate
    {
        public 
    $rowsperpage// variable to hold desired number of rows
        
    public $totalpages// variable to hold total number of pages
        
    public $range// variable to control number of links in page navigation
        
    public $text// variable to control pages linked to
        
    public $offset// variable to declare offset
        
    public $currentpage 0// variable to house currentpage

        /* the following function performs the pagination by assigning the appropriate values to each variable*/
        
    public function paginate(&$numrows$row 4)
        {
            
    // set maximum rows per page
            
    $this->rowsperpage $row;
            
    // get total pages
            
    $this->totalpages ceil($numrows/$this->rowsperpage);
            
    //get current page or set default
            
    if (isset($_GET['currentpage']) && is_numeric($_GET['currentpage']))
            {
                
    $this->currentpage = (int) $_GET['currentpage'];
            }
            else
            {
                
    $this->currentpage 1;
            }
            
    // make sure that the last page is really last
            
    if ($this->currentpage $this->totalpages)
            {
                
    $this->currentpage $this->totalpages;
            }
            else;
            
    // make sure there is no number less than 1
            
    if ($this->currentpage 1)
            {
                
    $this->currentpage 1;
            }
            else;
            
    //offset data
            
    $this->offset = ($this->currentpage -1) * $this->rowsperpage;
        } 
    // end function

        // the following function displays the page navigator
        
    public function counter(&$display$numlinks 1)
        {
            if (
    $this->currentpage || $this->currentpage == $this->totalpages)
            {
                
    // show back link
                
    echo('<a href="http://'$_SERVER['SERVER_NAME'] . '/?content=' $display '&currentpage=1"><<</a>' '  |  ');
                
    // create go back one page variable
                
    $prevpage $this->currentpage -1;
                
    // create link to previous page
                
    echo('<a href="http://'$_SERVER['SERVER_NAME'] . '/?content=' $display '&currentpage=' $prevpage '"><</a>' '  |  ');
            }
            else;
            
    // create range to limit link display
            
    $this->range $numlinks;

            for (
    $x = ($this->currentpage $this->range); $x < (($this->currentpage $this->range) +1); $x++)
            {
                if (
    $x && $x <= $this->totalpages)
                {
                    if(
    $x == $this->currentpage)
                    {
                        echo(
    "<b>$x</b>");
                    }
                    else
                    {
                        echo(
    '<a href="http://' $_SERVER['SERVER_NAME'] . '/?content=' $display '&currentpage=' $x '">' $x '</a>');
                    }
                } 
    // end if
            
    // end for loop 
            
    if($this->currentpage == || $this->currentpage && $this->currentpage != $this->totalpages)
            {
                
    // create go forward one page variable
                
    $nextpage $this->currentpage +1;
                
    // create link to next page
                
    echo('  |  ' '<a href="http://'$_SERVER['SERVER_NAME'] . '/?content=' $display '&currentpage=' $nextpage '">></a>' '  |  ');
                
    // show last page link
                
    echo('<a href="http://'$_SERVER['SERVER_NAME'] . '/?content=' $display '&currentpage=' $this->totalpages .'">>></a>');
            }
            else;
        } 
    // end function

        // this function displays the position of the query
        
    function position()
        {
            echo(
    '<br>You are on page ' $this->currentpage ' of ' $this->totalpages ' pages.');
        } 
    // end function

        // this function returns the rowsperpage
        
    function getrowsperpage()
        {
            return 
    $this->rowsperpage;
        } 
    // end function

        // this function returns the offset
        
    function getoffset()
        {
            return 
    $this->offset;
        } 
    // end function

        
    function getpages()
        {
            return 
    $this->totalpages;
        } 
    // end function
    // end class
    ?>
     

Share This Page