PDO php pagination


PDO php pagination

我一直在尝试添加一个安全分页页面(从MySQL数据库)。在网上寻找一个我认为是sqj注入等免费后,我发现:http://www.phpro.org/tutorials/Pagination-with-PHP-and-PDO.html

然而,当我使用这个脚本时,我得到了错误:AH01215: PHP致命错误:调用未定义的方法pager::getPagerData()在/path....到..etc/index.php的第62行

第62行是:

$pager = Pager::getPagerData($_SESSION['total_records'], $limit, $page);

完整代码:

<?php
 /*** make it or break it ***/
 error_reporting(E_ALL);
 /*** begin the session ***/
 session_start();
 /*** include the database connection class ***/
 include 'db.php';
 /*** include the pager class ***/
 include 'pager.php';
 /*** set the page name ***/
 $page_name = htmlentities($_SERVER['PHP_SELF']);
 /*** set the number of results per page ***/
 $limit = 20;
 /*** check the SESSION array for the total_records ***/
 if(!isset($_SESSION['total_records']))
 {
    try
    {
        /*** first get the count of records ***/
        $sql = "SELECT count(id) AS total FROM tablename";
        $stmt = db::getInstance()->prepare($sql);
        $stmt->execute();
        $_SESSION['total_records'] = $stmt->fetch(PDO::FETCH_COLUMN);
    }
    catch (Exception $e)
    {
        $_SESSION['total_records'] = 0;
    }
 }
    /*** check for a page number in GET ***/
    if( filter_has_var(INPUT_GET, "page") == false)
    {
        /*** no page in GET ***/
        $page = 1;
    }
    /*** if the page number is not an int or not within range, assign it to page 1 ***/
     elseif(filter_var($_GET['page'], FILTER_VALIDATE_INT, array("min_range"=>1, "max_range"=>$_SESSION['total_records'])) == false)
     {
        $page = 1;
    }
    else
    {
        /*** if all is well, assign it ***/
        $page = (int)$_GET['page'];
    }
 /*** if we have no results then there is no point in going on ***/
 if($_SESSION['total_records'] == 0)
 {
    $content = 'No Records Available';
 }
 else
 {
    /*** feed the variables to the pager class ***/
    $pager = Pager::getPagerData($_SESSION['total_records'], $limit, $page);
    /*** retrieve the variables from the pager class ***/
    $offset = $pager->offset;
    $limit  = $pager->limit;
    $page   = $pager->page;
    /*** begin the menu ***/
    $menu = '';
    /*** if this is page 1 there is no previous link ***/
    if($page != 1)
    {
        $menu .= '<li><a href="'.$page_name.'?page='.($page - 1).'">&lt;&lt; PREV </a></li>';
    }
    /*** loop over the pages ***/
    for ($i = 1; $i <= $pager->num_pages; $i++)
    {
        if ($i == $pager->page)
        {
            $menu .= '<li class="selected">'.$i.'</li>';
        }
        else
        {
            $menu .= '<li><a href="'.$page_name.'?page='.$i.'">'.$i.'</a></li>'."'n";
        }
    }
    /*** if we are on the last page, we do not need the NEXT link ***/
    if ($page < $pager->num_pages)  
    {
        $menu .= '<li><a href="'.$page_name.'?page='.($page + 1).'"> NEXT &gt;&gt;</a></li>';
    }
    /*** our sql statement ***/
    $sql ='SELECT * FROM tablename LIMIT :limit OFFSET :offset';
    /*** run the query ***/
    $db = db::getInstance();
    $stmt = $db->prepare($sql);
    $stmt->bindParam(':limit', $limit, PDO::PARAM_INT);
    $stmt->bindParam(':offset', $offset, PDO::PARAM_INT);
    $stmt->execute();
    $res = $stmt->fetchAll(PDO::FETCH_ASSOC);
    /*** the elements table content ***/
    $content = '';
    foreach ($res as $el)
    {
        $content .= '
        <tr><td>'.$el['id'].'</td>
        <td>'.$el['metatitle'].'</td>
        <td>'.$el['date'].'</td></tr>';
    }
 }
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>PHP Pagination</title>
<style type="text/css">
ul{
    margin: 0 auto; 
    width: 395px;
    list-style-type:none;
}
li{
    display:inline;
}
li.selected{
    float:left;
    text-decoration:none;
    color:black;
    font-weight:bold;
    background-color: #c0c0c0;
    padding:10px;
    padding-bottom: solid 1px red;
}
a{ 
    float:left;
    text-decoration:none;
    color:green;
    padding:10px;
    padding-bottom: 1px;
}
a:hover{
    border-bottom: solid 1px red;
    padding-bottom: 1px;
}
table {
    clear:both;
    margin: 0 auto;
}
</style>
</head>
</body>
<ul>
    <?php echo $menu; ?>
</ul>
<table class="elements">
<thead>
<tr> <th>Atomic Number</th> <th>Latin</th> <th>English</th> </tr>
</thead>
<tbody>
 <?php echo $content; ?>
</tbody>
<tfoot>
<tr><th colspan="3">Table of elements</th> </tr>
</tfoot>
</table>
</body>
</html>

pager.php

<?php
/*
 * Example usage
 * $pager = new pager();
 * $pager->num_results = $product_count;
 * $pager->limit = $config->config_values['product']['display_num'];
 * $pager->page = $page_num;
 * $pager->menu_link = '/category/electrical';
 * $pager->menu_link_suffix = '/foo/bar'; ( optional )
 * $pager->css_class = 'fubar'; ( optional )
 * $pager->run();
 * echo $pager;
 *
*/
    class pager{
            /**
            *
            * Constructor, duh!
            *
            * @access       public
            * @param        $num_pages
            * @param        $limit
            * @param        $page
            *
            */
            public function __construct( $num_results=null, $limit=null, $page=null )
            {
                    if( !is_null( $num_results ) && !is_null( $limit ) && !is_null( $page ) )
                    {
                            $this->num_results = $num_results;
                            $this->limit = $limit;
                            $this->page = $page;
                            $this->run();
                    }
            }
            /**
            *
            * Settor
            *
            * @param        string  $name
            * @param        mixed   $value
            *
            */
            public function __set( $name, $value )
            {
                    switch( $name )
                    {
                            case 'menu_link_suffix':
                            case 'num_results':
                            case 'menu_link':
                            case 'css_class':
                            case 'num_pages':
                            case 'offset':
                            case 'limit':
                            case 'page':
                            $this->$name = $value;
                            break;
                            default: throw new 'Exception( "Unable to set $name" );
                    }
            }
            /**
            *
            * Gettor
            *
            * @param        string  $name
            *
            */
            public function __get( $name )
            {
                    switch( $name )
                    {
                            case 'menu_link_suffix':
                            case 'num_results':
                            case 'menu_link':
                            case 'css_class':
                            case 'num_pages':
                            case 'offset':
                            case 'limit':
                            case 'page':
                            return $this->$name;
                            break;
                            default: throw new 'Exception( "Unable to get $name" );
                    }
            }
            /**
             * @calculate paging inforomation
             *
             * @access public
             * @param int $num_pages
             * @param int $limit
             * @param $page
             * @return object
             *
             **/
            public function run()
            {
                    /*** the number of pages ***/
                    $this->num_pages = ceil( $this->num_results / $this->limit );
                    $this->page = max( $this->page, 1 );
                    $this->page = min( $this->page, $this->num_pages );
                    /*** calculate the offset ***/
                    $this->offset = ( $this->page - 1 ) * $this->limit;
            }
            /**
            *
            * return a HTML string representation of the pager links
            * The links are in an <ul> with a CSS class name
            *
            * @access       public
            * @retun        string
            *
            */
            public function __toString()
            {
                    $menu = '<ul';
                    $menu .= isset( $this->css_class ) ? ' class="'.$this->css_class.'"' : '';
                    $menu .= '>';
                    /*** if this is page 1 there is no previous link ***/
                    if($this->page != 1)
                    {
                            $menu .= '<li><a href="'.$this->menu_link.'/'.( $this->page - 1 );
                            $menu .= isset( $this->menu_link_suffix ) ? $this->menu_link_suffix : '';
                            $menu .= '">PREV</a></li>';
                    }
                    /*** loop over the pages ***/
                    for( $i = 1; $i <= $this->num_pages; $i++ )
                    {
                            if( $i == $this->page )
                            {
                                    $menu .= '<li class="active"><a href="'.$this->menu_link.'/'.$i;
                                    $menu .= isset( $this->menu_link_suffix ) ? $this->menu_link_suffix : '';
                                    $menu .= '">'.$i.'</a></li>';
                            }
                            else
                            {
                                    $menu .= '<li><a href="'.$this->menu_link.'/'.$i;
                                    $menu .= isset( $this->menu_link_suffix ) ? $this->menu_link_suffix : '';
                                    $menu .= '">'.$i.'</a></li>';
                            }
                    }
                    /*** if we are on the last page, we do not need the NEXT link ***/
                    if( $this->page < $this->num_pages )
                    {
                            $menu .= '<li><a href="'.$this->menu_link.'/'.( $this->page + 1 );
                            $menu .= isset( $this->menu_link_suffix ) ? $this->menu_link_suffix : '';
                            $menu .= '">Next</a></li>';
                    }
                    return $menu;
            }
    } /*** end of class ***/
    ?>

dp.php

<?php
class db{
/*** Declare instance ***/
private static $instance = NULL;
/**
*
* the constructor is set to private so
* so nobody can create a new instance using new
*
*/
private function __construct() {
  /*** maybe set the db name here later ***/
}
/**
*
* Return DB instance or create intitial connection
*
* @return object (PDO)
*
* @access public
*
*/
public static function getInstance() {
if (!self::$instance)
    {
    self::$instance = new PDO("mysql:host=localhost;dbname=DBNAME", 'USER', 'PASS');;
    self::$instance-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }
return self::$instance;
}
/**
*
* Like the constructor, we make __clone private
* so nobody can clone the instance
*
*/
private function __clone(){
}
} /*** end of class ***/
?>

任何想法?此外,如果您看到任何您认为安全性较弱的代码,请随时指出来:)

Thanks in advance

注。删除了此处的user/pass表名等

尝试将第62行改为:

$pager = pager::getPagerData($_SESSION['total_records'], $limit, $page);

你的类是用小写的'p'定义的。

然而,除非发生了一些神奇的事情,否则这个方法仍然没有在任何地方定义,所以我看不出这将如何工作。最好和这篇文章的作者取得联系并询问一下。

注意:

类名以大写字母开头被认为是最佳实践。

http://www.php-fig.org/psr/psr-1/