Samuel Asor
Samuel Asor

Reputation: 480

Errors with PHP pagination

I'm trying to create a pagination script for a link in this format: http://example.com/some-page/1 where 1 will indicate the current page being viewed.

So far, I've been able to come up with a pagination class, here it is below:

<?php
class Pagination {
    private $_db,
        $_properties = array(
            'max'       => 5,
            'page'      => 1,
            'total'     => 0,
            'pages'     => 0,
        );

    public function __construct() {
        $this->_db = DB::getInstance();
    }

    public function getPage($page = 2) {
        $this->_properties['page'] = (int)$page;
    }

    public function pageStart() {
        $start = ( $this->getPage() > 1 ) ? ( $this->getPage() * $this->pageLimit() ) : 0;
        return $start;
    }

    public function pageLimit($max = 5) {
        $this->_properties['max'] = (int)$max;
    }

    public function getData($query) {
        $data = $this->_db->query($query . "LIMIT {$this->pageStart()}, {$this->pageLimit()}");

        if ( $data->count() ) {
            $this->_properties['total'] = $data->count();
            return $data->results();
        }
        return false;
    }

    public function totalCount() {
        return $this->_properties['total'];
    }

    public function currentPage() {
        return $this->_properties['page'];
    }

    public function renderLinks() {
        $total = $this->totalCount();
        $perPage = $this->pageLimit();
        $pages = ceil($total / $perPage);
        $currentPage = $this->currentPage();

        $output = "<div class=\"col-md-12 col-xs-12 col-sm-12\">";
        $output .= "<ul class=\"pagination pagination-lg\">";
        $output .= "<li> <a href=\"". $_SERVER['REQUEST_URI'] . '/' . ($currentPage - 1) ."\"> <i class=\"fa fa-chevron-left\" aria-hidden=\"true\"></i></a></li>";

        for ($i = 1; $i <= $pages ; $i++) { 
            $status = ($currentPage == $i) ? " class=\"active\"" : "";
            $output .= "<li". $status ." > <a href=\"/". $i ."\">". $i ."</a> </li>";

        }

        $output .= "<li><a href=\"/". $_SERVER['REQUEST_URI'] . '/' . $i ."\"> <i class=\"fa fa-chevron-right\" aria-hidden=\"true\"></i></a></li>";
        $output .= "<ul>";
        $output .= "</div>";

        return $output;
    }
}

And I call it in the page where I need it like so:

$userServices = new Pagination();
$userServices->getPage($thirdvar);
$userServices->pageLimit(2);
$servicesData = $userServices->getData("SELECT * FROM `table` WHERE `id` = 4");

Then I do a foreach loop to get the contents of the $serviceData, like so:

foreach ( $serviceData as $service ) {
    // output content here
}

Then for the navigation links:

<?php echo $userServices->renderLinks(); ?>

When I ran the page, I got an error: Warning: Division by zero in C:\xampp7\htdocs\directory\model\Pagination.php on line 49. That is, where I have $pages = ceil($total / $perPage); and also this error: Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 65011744 bytes) in C:\xampp7\htdocs\directory\model\Pagination.php on line 58, where I have $output .= "<li". $status ." > <a href=\"/". $i ."\">". $i ."</a> </li>";.

So far, when I manually input a number to replace the $pages = ceil($total / 4);, the errors disappear, but I do not get the data in the page.

Where am I doing it wrong?

EDIT

So after making some corrections (based on answers and comments), I figured out that the reason why no data is being populated is from this line: $data = $this->_db->query($query . "LIMIT $this->pageStart(), $this->pageLimit()");. For who-know-why, I don't know why $this->pageStart() and $this->pageLimit() are not returning any values, thereby making the query to fail.

Can someone please point me to the right path?

Upvotes: 1

Views: 288

Answers (3)

Samuel Asor
Samuel Asor

Reputation: 480

So after so much debugging, and also from the insights given in some comments, I was able to figure out the problem of my pagination class.

First, I updated my getData() method to:

public function getData($query) {
    $data = $this->_db->query("{$query} LIMIT {$this->pageStart()}, {$this->pageLimit()}");

    if ( $data->count() ) {
        return $data->results();
    }
    $tQuery = $this->_db->query("SELECT FOUND_ROWS() AS total");
    $this->_properties['total'] = $tQuery->first()->total;
}

and then called it in my page using:

$servicesData = $userServices->getData("SELECT SQL_CALC_FOUND_ROWS * FROM `table` WHERE `id` = 1");

Also, I added some new methods renderPage(), renderLimit(), baseUrl() and renderUrl() which will return the values of getPage(), pageLimit(), get the url structure that will be entered, and return the value of baseUrl() respectively.

Then I also updated the renderLinks() method like so:

public function renderLinks() {
    $total = $this->totalCount();
    $perPage = $this->renderLimit();
    $pages = ceil($total / $perPage);
    $currentPage = $this->renderPage();
    $prevCalc = $currentPage - 1;
    $prevStat = ($prevCalc == 0) ? "" : " href=\"". $this->renderUrl() . $prevCalc ."\"";
    $nextCalc = $currentPage + 1;
    $nextStat = ($nextCalc > $pages) ? "" : " href=\"". $this->renderUrl() . $nextCalc ."\"";

    $output = "<div class=\"col-md-12 col-xs-12 col-sm-12\">";
    $output .= "<ul class=\"pagination pagination-lg\">";
    $output .= "<li> <a". $prevStat ."> <i class=\"fa fa-chevron-left\" aria-hidden=\"true\"></i></a></li>";

    for ($i = 1; $i <= $pages ; $i++) { 
        $status = ($currentPage == $i) ? " class=\"active\"" : "";
        $output .= "<li". $status ." > <a href=\"". $this->renderUrl() . $i ."\">". $i ."</a> </li>";

    }

    $output .= "<li><a". $nextStat ."> <i class=\"fa fa-chevron-right\" aria-hidden=\"true\"></i></a></li>";
    $output .= "<ul>";
    $output .= "</div>";

    return $output;
}

So in all, my Pagination Class looks like so:

<?php
class Pagination {
    private $_db,
        $_properties = array(
            'max'       => 5,
            'page'      => 1,
            'total'     => 4,
            'base_url'  => '',
        );

    public function __construct() {
        $this->_db = DB::getInstance();
    }

    public function getPage($page = null) {
        return( $page && $page != "" ) ? $this->_properties['page'] = (int)$page : $this->_properties['page'];
    }

    public function renderPage() {
        return $this->_properties['page'];
    }

    public function pageLimit($max = null) {
        return( $max ) ? $this->_properties['max'] = (int)$max : $this->_properties['max'];
    }

    public function renderLimit() {
        return $this->_properties['max'];
    }

    public function pageStart() {
        return( $this->renderPage() > 1 ) ? ($this->renderPage() * $this->renderLimit()) - $this->pageLimit() : 0;
    }

    public function getData($query) {
        $data = $this->_db->query("{$query} LIMIT {$this->pageStart()}, {$this->pageLimit()}");

        if ( $data->count() ) {
            return $data->results();
        }
        $tQuery = $this->_db->query("SELECT FOUND_ROWS() AS total");
        $this->_properties['total'] = $tQuery->first()->total;
    }

    public function totalCount() {
        return $this->_properties['total'];
    }

    public function baseUrl($url = null) {
        return( $url ) ? $this->_properties['base_url'] = escape_url($url) : $this->_properties['base_url'];
    }

    public function renderUrl() {
        return $this->_properties['base_url'];
    }

    public function renderLinks() {
        $total = $this->totalCount();
        $perPage = $this->renderLimit();
        $pages = ceil($total / $perPage);
        $currentPage = $this->renderPage();
        $prevCalc = $currentPage - 1;
        $prevStat = ($prevCalc == 0) ? "" : " href=\"". $this->renderUrl() . $prevCalc ."\"";
        $nextCalc = $currentPage + 1;
        $nextStat = ($nextCalc > $pages) ? "" : " href=\"". $this->renderUrl() . $nextCalc ."\"";

        $output = "<div class=\"col-md-12 col-xs-12 col-sm-12\">";
        $output .= "<ul class=\"pagination pagination-lg\">";
        $output .= "<li> <a". $prevStat ."> <i class=\"fa fa-chevron-left\" aria-hidden=\"true\"></i></a></li>";

        for ($i = 1; $i <= $pages ; $i++) { 
            $status = ($currentPage == $i) ? " class=\"active\"" : "";
            $output .= "<li". $status ." > <a href=\"". $this->renderUrl() . $i ."\">". $i ."</a> </li>";

        }

        $output .= "<li><a". $nextStat ."> <i class=\"fa fa-chevron-right\" aria-hidden=\"true\"></i></a></li>";
        $output .= "<ul>";
        $output .= "</div>";

        return $output;
    }
}

Hope it helps some other person(s) out there.

Upvotes: 0

Rajendran Nadar
Rajendran Nadar

Reputation: 5438

This should fix the 2nd error

ini_set('memory_limit','16M');

Instead of 16M pass hight value that is required(I left the math for you). But this is not a good practice make you code more efficient.

Pu this before the 49 line

die($perPage);

And put the output. So that I can help you.

EDIT:

You need to work on you code lot of issues. Remove the die();

Upvotes: 0

delboy1978uk
delboy1978uk

Reputation: 12365

$perPage = $this->pageLimit();

Yet the pageLimit() function doesn't return anything. That's the problem.

Upvotes: 2

Related Questions