Reputation: 480
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
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
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
Reputation: 12365
$perPage = $this->pageLimit();
Yet the pageLimit()
function doesn't return anything. That's the problem.
Upvotes: 2