3

I have a website that I am creating for showing reports. all the reports are in table format and are pulled from SQL using PHP. I have the pages working except they take a long time to pull the data when there are more than a few hundred rows. There are usually more than 30 columns in these table. I would like to know if there is a way to either make the tables load faster or, preferably, split the tables into multiple pages that will have navigation buttons at the bottom to move forward or backward through the table.

I am trying to do this using only PHP, HTML and CSS. I don't have direct access to the servers where the code resides, just to my code. so updating anything other than my code would be very difficult.

Here is the code that I've got for pulling and displaying that tables now:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>QDef</title>
        <link rel="StyleSheet" href="StyleSheet.css" type="text/css">
    </head>
    <body>
        <div class="menu-wrap">
            <nav class="menu">
                <ul class="clearfix">
                    <li><a href="default.aspx">Home</a></li>
                    <li><a href="#">Material Tracking</a>
                        <ul class="sub-menu">
                            <li><a href="SearchStateProject.php">Search by State or Contract Number</a></li>
                            <li><a href="MaterialTrackingAllStates.php">All Contracts</a></li>
                        </ul>
                    </li>
                    <li><a href="#">OPR Reports</a>
                        <ul class="sub-menu">
                            <li><a href="COEI_OPR_Filtered.php">COEI OPR Filtered</a></li>
                            <li><a href="OSP_OPR_Filtered.php">OSP OPR Filtered</a></li>
                        </ul>
                    </li>
                    <li><a href="#">Admin</a>
                        <ul class="sub-menu">
                            <li><a href="QDef.php">QDef</a></li>
                            <li><a href="CheckPHP.php">PHP Check</a></li>
                            <li><a href="EditQDefForm.php">Edit QDef form</a></li>
                            <li><a href="FormToEditMaterial.php">Form to Edit Material</a></li>
                            <li><a href="TableUpdates.php">Table Updates</a></li>
                        </ul>
                    </li>
                </ul>
            </nav>
        </div>
        <br>
        <br>
        <h1>QDef Table</h1>
<?php
    $configs = include('DBConn.php');
    $servername = $configs['ServerName'];
    $username = $configs['UserName'];
    $password = $configs['Password'];
    $dbname = $configs['DBName'];
    $limit = 15; 

    try
    {
        $conn = new PDO("sqlsrv:server=$servername;database=$dbname", $username,$password);
        //set the PDO error mode to exception
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $conn->setAttribute(PDO::SQLSRV_ATTR_QUERY_TIMEOUT, 1);
        //echo "Connected Successfully<br>" /*. $conn*/;
        /*If conncected see if we can pull any data!*/
    }
    catch(Exception $e)
    {
        die( print_r( $e->getMessage()));
    }

    $TotalRows = $conn->query('select count(*) from pmdb.v_QDefs')->fetchColumn(); //How many rows in the table
    $pages = ceil($TotalRows / $limit); //How many page will there be
    $currentpage = 1;
    $currentpage = min($pages, filter_input(input_get, 'page', filter_validate_int, array('options' => array('default' => 1,'min_range' => 1,),))); //What page are you currently on
    var_dump($currentpage);
    $offset = abs(($currentpage - 1) * $limit); //Calculate Offset
    //Some info to display to the user?
    $start = $offset + 1;
    $end = min(($offset + $limit),$TotalRows);
    $prevlink = ($currentpage > 1) ? '<a href="?page=1" title="First page">&laquo;</a> <a href="?page=' . ($currentpage - 1) . '" title="Previous page">&lsaquo;</a>' : '<span class="disabled">&laquo;</span> <span class="disabled">&lsaquo;</span>'; //the back link
    $nextlink = ($currentpage < $pages) ? '<a href="?page' . ($currentpage + 1) . '" title="Next page">&rsaquo;</a> <a href="?page=' . $pages . '" title="Last page">&raquo;</a>' : '<span class="disabled">&rsaquo;</span> <span class="disabled">&raquo;</span>'; //the Forward link
    echo '<div id="paging"><p>', $prevlink, ' Page ',$currentpage, ' of ',$pages,' pages, displaying ',$start,'-',$end, ' of ',$TotalRows,' results ',$nextlink,' </p></div>'; //display the paging information

    $tsql = "select Id,QSrc,QName,isActive,RunReport,FilePath,QDef from pmdb.v_QDefs order by Id OFFSET $offset ROWS FETCH NEXT $limit ROWS";
    //echo $tsql . "<br>";
    $getqueries = $conn->query($tsql);

    $queries = $getqueries->fetchALL(PDO::FETCH_ASSOC);

    $countqueries = count($queries);

    if(isset($countqueries))
    {
        if($countqueries > 0)
        {
            //echo "There are queries returned";
            BeginQueriesTable($countqueries);
                $CountValues = 1;
            foreach($queries as $query)
            {
                PopulateQueryTable($query,$CountValues);
                $CountValues = !$CountValues;
            }
            EndQueriesTable();
        }
        else
        {
            echo "<br>Values returned: $countqueries";
        }
    }
    else
    {
        echo "No count";
    }

    function BeginQueriesTable($rowCount)
    {
        $headings = array("Edit","Id","QSrc","QName","isActive","RunReport","FilePath","QDef");
        echo "<p class=" . chr(34) . "headings" . chr(34) . ">$rowCount Results</p>";
        echo "<table class=" . chr(34) . "tab" . chr(34) . "id=" . chr(34) . "OuterTable" . chr(34) . ">";
        echo "<tr>";
        foreach($headings as $heading)
        {
            echo "<th class=" . chr(34) . "cell" . chr(34) . ">$heading</th>";
        }
        echo "</tr>";
    }

    function PopulateQueryTable($values,$Number)
    {
        $queryID = $values['Id'];
        //var_dump($values);
        //echo "<br/>";
        //var_dump ($queryID);
        echo "<tr class=" . chr(34) . "row" . ($Number) . chr(34) . "><td><a href=" . chr(34) . "EditQDefForm.php?id=" . $values['Id'] . chr(34) . ">Edit</a></td>";
        foreach($values as $key=>$value)
        {
            if(!is_null($value))
            {
                echo "<td>$value</td>";
            }
            else
            {
                echo "<td></td>";
            }
        }
        echo "</tr>";
    }

    function EndQueriesTable()
    {
        echo "</table><br/>";
    }
?>
    </body>
</html>

Right now this table will pull about 15000 rows. I know this isn't huge, but it takes 5 - 10 minutes to load because there are 61 columns some of which are Comments that are very long.

Let me know if you need more info, any help would be very appreciated.

Mike
  • 1,853
  • 3
  • 45
  • 75
  • 1
    On a side note: I suggest you use a separate config file for your SQL connection... – Bubble Hacker Jun 17 '16 at 14:12
  • @BubbleHacker If I put it in a separate config file how would I link to it? Can you show me some example or documentation on it? i have several tables that I could do that to. – Mike Jun 17 '16 at 14:14
  • 1
    Using php's `include` function. – Bubble Hacker Jun 17 '16 at 14:15
  • 1
    http://stackoverflow.com/questions/3705318/simple-php-pagination-script – Marc B Jun 17 '16 at 14:18
  • @MarcB I've been using the example from the link that you provided. i'm having a problem with the `$currentpage`, it comes up as `NULL` and so I never get any data back because it is trying to show page `NULL` instead of page 1. I'm updating the code I have above to show my updates. – Mike Jun 17 '16 at 15:39
  • @BubbleHacker Thank you for the comment on using a separate config file. I've done so for all of my tables. – Mike Jun 17 '16 at 15:44
  • @MarcB I've tried looking into this as much as I can. The only thing I could find is that `filter_input` returns `NULL` when the `variable` is not set. So I tried `$currentpage = 1;` directly above. Still gets set back to `NULL`. I've updated my code above to reflect the changes I've made. I cannot figure out where the error is. – Mike Jun 17 '16 at 17:11

2 Answers2

0

The main idea is to use MySQL Limit: e.g:

$sql = "SELECT * FROM mytable LIMIT 10 OFFSET 15";

you can pass the page number as a query to the NEXT and Previous links:

$rec_limit=50; //Your favorite paging number
 if( isset($_GET{'page'} ) ) {
            $page = $_GET{'page'} + 1;
            $offset = $rec_limit * $page ;
         }else {
            $page = 0;
            $offset = 0;
         }
$sql = "SELECT * from mytable LIMIT $offset, $rec_limit";

check here for more details on creating next and previous links etc.

Ali Sheikhpour
  • 10,475
  • 5
  • 41
  • 82
0

i have figured it out with help from the link that @markb sent in the comments above (sql-Simple PHP Pagination Script). I ended up using the link in that answer:

Basic pagination tutorial

I tried with the accepted answer to the question, but could not get it to work. Here is what I got to work for me:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>QDef</title>
        <link rel="StyleSheet" href="StyleSheet.css" type="text/css">
    </head>
    <body>
        <div class="menu-wrap">
            <nav class="menu">
                <ul class="clearfix">
                    <li><a href="default.aspx">Home</a></li>
                    <li><a href="#">Material Tracking</a>
                        <ul class="sub-menu">
                            <li><a href="SearchStateProject.php">Search by State or Contract Number</a></li>
                            <li><a href="MaterialTrackingAllStates.php">All Contracts</a></li>
                        </ul>
                    </li>
                    <li><a href="#">OPR Reports</a>
                        <ul class="sub-menu">
                            <li><a href="COEI_OPR_Filtered.php">COEI OPR Filtered</a></li>
                            <li><a href="OSP_OPR_Filtered.php">OSP OPR Filtered</a></li>
                        </ul>
                    </li>
                    <li><a href="#">Admin</a>
                        <ul class="sub-menu">
                            <li><a href="QDef.php">QDef</a></li>
                            <li><a href="CheckPHP.php">PHP Check</a></li>
                            <li><a href="EditQDefForm.php">Edit QDef form</a></li>
                            <li><a href="FormToEditMaterial.php">Form to Edit Material</a></li>
                            <li><a href="TableUpdates.php">Table Updates</a></li>
                        </ul>
                    </li>
                </ul>
            </nav>
        </div>
        <br>
        <br>
        <h1>QDef Table</h1>
<?php
    $configs = include('DBConn.php');
    $servername = $configs['ServerName'];
    $username = $configs['UserName'];
    $password = $configs['Password'];
    $dbname = $configs['DBName'];
    $limit = 15; //Create the max limit per page

    try
    {
        $conn = new PDO("sqlsrv:server=$servername;database=$dbname", $username,$password);
        //set the PDO error mode to exception
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $conn->setAttribute(PDO::SQLSRV_ATTR_QUERY_TIMEOUT, 1);
        //echo "Connected Successfully<br>" /*. $conn*/;
        /*If conncected see if we can pull any data!*/
    }
    catch(Exception $e)
    {
        die( print_r( $e->getMessage()));
    }
    //How many rows in the table
    $TotalRows = $conn->query('select count(*) from pmdb.v_QDefs')->fetchColumn();
    //How many pages will there be
    $pages = ceil($TotalRows / $limit);
    //echo $pages;
    if(isset($_GET['currentpage']))
    {
        //var_dump($_GET);
        $currentpage = $_GET['currentpage'];
    }
    else
    {
        $currentpage = 1;
    }

    // if current page is greater than total pages...
    if ($currentpage > $pages) 
    {
       $currentpage = $pages;
    } 

    // if current page is less than first page...
    if ($currentpage < 1) 
    {
       $currentpage = 1;
    } 
    //Calculate Offset
    $offset = abs(($currentpage - 1) * $limit);

    $range = 3;
    echo "<p>";
    if($currentpage > 1)
    {
        echo "<a href='{$_SERVER['PHP_SELF']}?currentpage=1'> << </a> ";
        $prevpage = $currentpage - 1;
        echo " <a href='{$_SERVER['PHP_SELF']}?currentpage=$prevpage'> < </a> ";
    }
    //Setting the number of links for pages around the current page
    for ($x = ($currentpage - $range); $x < (($currentpage + $range) + 1); $x++)
    {
        if (($x > 0) && ($x <= $pages))
        {
            if ($x == $currentpage)
            {
                echo "[<b>$x</b>]";
            }
            else 
            {
                echo "<a href='{$_SERVER['PHP_SELF']}?currentpage=$x'>$x</a>";
            }
        }
    }

    if ($currentpage != $pages)
    {
        $nextpage = $currentpage + 1;
        echo "<a href='{$_SERVER['PHP_SELF']}?currentpage=$nextpage'> > </a>";
        echo "<a href='{$_SERVER['PHP_SELF']}?currentpage=$pages'> >> </a>";
    }
    echo "</p>";
    //Some info to display to the user?
    $start = $offset + 1;
    $end = min(($offset + $limit),$TotalRows);
    echo '<div id="paging"><p>',' Page ',$currentpage, ' of ',$pages,' pages, displaying ',$start,'-',$end, ' of ',$TotalRows,' results ',$nextlink,' </p></div>'; //display the paging information

    $tsql = "select Id,QSrc,QName,isActive,RunReport,FilePath,QDef from pmdb.v_QDefs order by Id OFFSET $offset ROWS FETCH NEXT $limit ROWS ONLY";

    $getqueries = $conn->query($tsql);

    $queries = $getqueries->fetchALL(PDO::FETCH_ASSOC);

    $countqueries = count($queries);

    if(isset($countqueries))
    {
        if($countqueries > 0)
        {
            //echo "There are queries returned";
            BeginQueriesTable($countqueries);
                $CountValues = 1;
            foreach($queries as $query)
            {
                PopulateQueryTable($query,$CountValues);
                $CountValues = !$CountValues;
            }
            EndQueriesTable();
        }
        else
        {
            echo "<br>Values returned: $countqueries";
        }
    }
    else
    {
        echo "No count";
    }

    function BeginQueriesTable($rowCount)
    {
        $headings = array("Edit","Id","QSrc","QName","isActive","RunReport","FilePath","QDef");
        echo "<table class=" . chr(34) . "tab" . chr(34) . "id=" . chr(34) . "OuterTable" . chr(34) . ">";
        echo "<tr>";
        foreach($headings as $heading)
        {
            echo "<th class=" . chr(34) . "cell" . chr(34) . ">$heading</th>";
        }
        echo "</tr>";
    }

    function PopulateQueryTable($values,$Number)
    {
        $queryID = $values['Id'];
        echo "<tr class=" . chr(34) . "row" . ($Number) . chr(34) . "><td><a href=" . chr(34) . "EditQDefForm.php?id=" . $values['Id'] . chr(34) . ">Edit</a></td>";
        foreach($values as $key=>$value)
        {
            if(!is_null($value))
            {
                echo "<td>$value</td>";
            }
            else
            {
                echo "<td></td>";
            }
        }
        echo "</tr>";
    }

    function EndQueriesTable()
    {
        echo "</table><br/>";
    }
?>
    </body>
</html>

This is now working and currently shows 15 rows per page. I used that number simply to make it quick. I'll be uping the number of rows before I complete the website.

Community
  • 1
  • 1
Mike
  • 1,853
  • 3
  • 45
  • 75