I need to paginate some JSON result using PHP but as per my code its not working as expected. I am explaining my code below.
<?php
$arr='[{"sku":"Pizza001","position":0,"category_id":"67"},{"sku":"Birthday Cake","position":0,"category_id":"67"},{"sku":"Birthday Cake-1","position":0,"category_id":"67"},{"sku":"Fruit cake","position":0,"category_id":"67"},{"sku":"Birthday Cake for Gift","position":0,"category_id":"67"}]';
$raw_data = json_decode($arr, true);
paginate($raw_data,1);
function paginate($data, $page = 2, $perPage = 2) {
$x = ($page - 1) * $perPage;
$z = $page * $perPage;
$y = ($z > count($data)) ? count($data) : $z;
for(; $x < $y; $x++) {
print_r($data[$x]);
}
}
?>
Here I am getting always first 2 set o data from JSON object. I need as per $page and $perPage the data will be filtered. Suppose $page=1 and $perPage=2 then the first 2 set of record will be fetched and if $page=2 and $perPage=2 then next 2 set(i.e-from 2nd index) of data will be fetched and so on. Please help me to resolve this issue.
I have used a simple logic using array_slice as suggested by Wenchoeng Young Here you go:
$i=0;
$page=5;
$perPage=1;
$arr='[
{"sku":"Pizza001","position":0,"category_id":"67"},
{"sku":"Birthday Cake","position":0,"category_id":"67"},
{"sku":"Birthday Cake-1","position":0,"category_id":"67"},
{"sku":"Fruit cake","position":0,"category_id":"67"},
{"sku":"Birthday Cake for Gift","position":0,"category_id":"67"}
]';
$raw_data = json_decode($arr, true);
paginate($raw_data, $page, $perPage);
function paginate($data, $page, $perPage)
{ print_r(array_slice($data, $page-1, $perPage)); }
Use dynamic variable for the page number and limit your records per page. On click of page number it automatically changes the results.
<?php
$arr = '[{"sku":"Pizza001","position":0,"category_id":"67"},{"sku":"Birthday Cake","position":0,"category_id":"67"},{"sku":"Birthday Cake-1","position":0,"category_id":"67"},{"sku":"Fruit cake","position":0,"category_id":"67"},{"sku":"Birthday Cake for Gift","position":0,"category_id":"67"}]';
$raw_data = json_decode($arr, true);
paginate($raw_data, 1);
function paginate($data, $page = $pageNumber, $perPage = $limit)
{
$x = ($page - 1) * $perPage;
$z = $page * $perPage;
$y = ($z > count($data)) ? count($data) : $z;
for (; $x < $y; ++$x) {
print_r($data[$x]);
}
}
Related
I'm currently trying to make some pagination work, but without any success.
The first query I'm executing is to grab all the data needed: so first result should be on the first page, second result on the second and so on... But I'm always getting the first result. Although I copied the query into phpmyadmin to manualy set the query and there it showed me the right results.
Here's the code where everything is happening. I'm stuck why it won't work.
$page = isset($_GET['page']) ? $_GET['page'] : 1;
$limit = 1;
$start = 0;
$query = $db->prepare("SELECT * FROM `users` LIMIT $limit OFFSET $start");
$query->execute();
$result = $query->fetchAll(PDO::FETCH_OBJ);
$count = count($result);
$query2 = $db->prepare("SELECT * FROM `users`");
$query2->execute();
$result2 = $query2->fetchALL(PDO::FETCH_OBJ);
$count2 = count($result2);
// Pagination
$total = ceil($count2 / $limit);
if ($page > 1) {
$start = ($page - 1) * $limit;
}
if ($page != $total) {
$next_page = '<li>»</li>';
} else {
$next_page = '<li class="disabled">»</li>';
}
if ($page > 1) {
$previous_page = '<li>«</li>';
} else {
$previous_page = '<li class="disabled">«</li>';
}
What am I doing wrong?
You are doing nothing with $page. $start is always 0 in the query.
You're going to need to define how many records you want per page, then multiply that by $page -1, e.g.
$start = ($page - 1) * $records_per_page;
I currently have a method inside my "car class" that display the car:
static function getCars(){
$autos = DB::query("SELECT * FROM automoviles");
$retorno = array();
foreach($autos as $a){
$automovil = automovil::fromDB($a->marca, $a->modelo, $a->version, $a->year, $a->usuario_id, $a->kilometraje, $a->info,
$a->hits, $a->cilindrada, $a->estado, $a->color, $a->categoria, $a->precio, $a->idAutomovil);
array_push($retorno, $automovil);
}
return $retorno;
}
In my index.php I call that function
foreach(car::getCars() as $a){
That allows me to display the info this way ( of course inside the foreach I have a huge code with the details I'll display.
Is there a way to implement a pagination to that thing so I can handle 8 cars per page, instead of showing all of them at the same page?
You can add a $limit and $page parameter on your function so that it will only return a maximum of $limit number of items starting from $limit * $page(or will call it the $offset). You also need to add a function to get the total number of rows you have for automoviles table.
static function getCars($page = 0, $limit = 8){
$offset = $limit * max(0, $page - 1);
//replace this with prepared statement
$autos = DB::query("SELECT * FROM automoviles LIMIT $offset, $limit");
$retorno = array();
foreach($autos as $a){
$automovil = automovil::fromDB($a->marca, $a->modelo, $a->version, $a->year, $a->usuario_id, $a->kilometraje, $a->info,
$a->hits, $a->cilindrada, $a->estado, $a->color, $a->categoria, $a->precio, $a->idAutomovil);
array_push($retorno, $automovil);
}
return $retorno;
}
static function getTotal()
{
//query to get total number of rows in automoviles table
}
In your index.php do this:
foreach(car::getCars((isset($_GET['page']) ? $_GET['page'] : 1)) as $a){
...
}
and add the pagination links.
$total = car::getTotal();
if($total > 8) {
for($i = 1; $i <= intval(ceil(1.0 * $total / $limit)); $i++) {
echo '' . $i . ';
}
}
I have the following code for the pagination(PHP) in MongoDB database.
<?php
$mongodb = new Mongo("vvv");
$database = fff
$collection = gggg
$page = isset($_GET['page']) ? (int) $_GET['page'] : 1;
$limit = 12;
$skip = ($page - 1) * $limit;
$next = ($page + 1);
$prev = ($page - 1);
$sort = array('createdAt' => -1);
$cursor = $collection->find()->skip($skip)->limit($limit)->sort($sort);
foreach ($cursor as $r) {
--------
}
$total= $cursor->count();
if($page > 1){
echo 'Previous';
if($page * $limit < $total) {
echo ' Next';
}
} else {
if($page * $limit < $total) {
echo ' Next';
}
}
$mongodb->close();
?>
BUT my database size is 30GB+, each search provides the results of 20,000 which takes HUGE TIME to count() //$total= $cursor->count();
Can any one provide any PHP pagination code for MongoDB which does not count the total number of results but do the pagination?
cursor.skip() requires the server to walk from the beginning of the collection or index to get the offset or skip position before beginning to return results. It is not recommended to use it in pagination against 30GB+ data in your case.
If you cannot narrow a little bit your condition in find(), you can consider to add a sequence number in your docs for pagination purpose, assuming that you will rarely remove/update those documents:
{
createdAt: "2015-01-01",
...
seq_no: 1
},
{
createdAt: "2015-01-02",
...
seq_no: 2
}
Then you can implement the pagination query like this (remember to create the index on seq_no, of course):
$cursor = $collection->find({"seq_no": {"$gt":$skip, "$lte":($skip+$limit)}})
This question already has answers here:
How to Paginate lines in a foreach loop with PHP
(2 answers)
Closed 9 years ago.
Below is code I'm using to parse XML file, however file has many records and I want to paginate it, and display 20 records per page.
I also want the pagination links at bottom of page so users can go to other pages as well. It should be something like, if no value is give then it will start from 0 to 20 else if value is 2 start from 40 and stop at 60, test.php?page=2.
$xml = new SimpleXMLElement('xmlfile.xml', 0, true);
foreach ($xml->product as $key => $value) {
echo "$value->name";
echo "<br>";
}
Something like this should work:
<?php
$startPage = $_GET['page'];
$perPage = 10;
$currentRecord = 0;
$xml = new SimpleXMLElement('xmlfile.xml', 0, true);
foreach($xml->product as $key => $value)
{
$currentRecord += 1;
if($currentRecord > ($startPage * $perPage) && $currentRecord < ($startPage * $perPage + $perPage)){
echo "$value->name";
//echo $value->name;
echo "<br>";
}
}
//and the pagination:
for ($i = 1; $i <= ($currentRecord / $perPage); $i++) {
echo("<a href='thispage.php?page=".$i."'>".$i."</a>");
} ?>
You could use php's array_slice function (Documentation: http://www.php.net/manual/en/function.array-slice.php)
Start would be $page * $itemsPerPage, end would be $page * $itemsPerPage + $itemsPerPage and the number of pages would be ceil(count($xml->product) / $itemsPerPage).
Example:
$allItems = array(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
$itemsPerPage = 5;
$page = isset($_GET['page']) ? intval($_GET['page']) : 0;
foreach (array_slice($allItems, $page * $itemsPerPage, $page * $itemsPerPage + $itemsPerPage) as $item) {
echo "item $item";
}
It even works :) see: http://codepad.org/JiOiWcD1
As SimpleXMLElement is a Traversable, you can do the pagination with a LimitItertor which ships with PHP.
To get the total number of product elements you can use the SimpleXMLElement::count() function.
Pagination works like outlined in the hundreds of other questions, I preferable use the LimitPagination type for it.
It takes the current page, the total amount of elements and elements per page as arguments (see as well: PHP 5.2 and Pagination). It also has a helper function to provide the LimitIterator.
Example:
$products = $xml->product;
// pagination
$pagination = new LimitPagination($_GET['page'], $products->count(), 20);
foreach ($pagination->getLimitIterator($products) as $product) {
...
}
If you want to output a pager that allows to navigate between the pages, the LimitPagination has more to offer to make that a bit easier, e.g. for just all pages highlighting the current page (here exemplary with brackets):
foreach ($pagination->getPageRange() as $page)
{
if ($page === $pagination->getPage()) {
// current page
printf("[p%d] ", $page);
} else {
printf("p%d ", $page);
}
}
foreach ($pagination->getPageRange() as $page)
{
if ($page === $pagination->getPage()) {
// current page
printf("[p%d] ", $page);
} else {
printf("p%d ", $page);
}
}
Interactive online demo: http://codepad.viper-7.com/OjvNcO
Less interactive online demo: http://eval.in/14176
I am trying to create a dynamic page links created based on the number of rows in a mysql table. I would like to display 10 results per page and wish to have the php script create links to additional pages.
So I was thinking of using the num_rows and dividing it by 10 however if I have 53 rows the return would be 5.3 where as I would need 6 pages and not 5. I am thinking of using the round function and looping it through a for I statement until $pages > $rows_rounded. And every 10 rows add a link to pages($i) Is this the best method to acheive this or there an alternative simpler route to take?
pagenator class I made. getCurrentPages() returns all the pages you should be displaying in an array. so if you are on page one, and you want to display a total of 9 pages, you would get an array 1-9. if you were on page 10 however, your would get back an array 6-14. if there are 20 total pages and you are on page 20, you would get back an array 11-20.
<?php
class Lev_Pagenator {
private $recordsPerPage;
private $currentPage;
private $numberOfTotalRecords;
private $lastPage = null;
public function __construct($current_page, $number_of_total_records, $records_per_page = 25) {
$this->currentPage = $current_page;
$this->numberOfTotalRecords = $number_of_total_records;
$this->recordsPerPage = $records_per_page;
}
public function getCurrentStartIndex() {
return ($this->currentPage - 1) * $this->recordsPerPage;
}
public function getCurrentPages($number_of_pages_to_display = 9) {
$start_page = $this->currentPage - floor($number_of_pages_to_display / 2);
if ($start_page < 1) $start_page = 1;
$last_page = $this->getLastPage();
$pages = array($start_page);
for ($i = 1; $i < $number_of_pages_to_display; $i++) {
$temp_page = $start_page + $i;
if ($temp_page <= $last_page) {
$pages[] = $temp_page;
} else {
break;
}
}
return $pages;
}
public function getPreviousPage() {
if ($this->currentPage === 1) return false;
return $this->currentPage - 1;
}
public function getNextPage() {
if ($this->currentPage === $this->getLastPage) return false;
return $this->currentPage + 1;
}
public function getLastPage() {
if ($this->lastPage === null) $this->lastPage = ceil($this->numberOfTotalRecords / $this->recordsPerPage);
return $this->lastPage;
}
}
?>
EDIT (USAGE):
<?php
$pagenator = new Lev_Pagenator($current_page, $number_of_total_records, $records_per_page);
$pages_array = $pagenator->getCurrentPages($number_of_pages_to_display);
?>
The idea of a for loop sounds like a good one, you would use something like:
$rows_rounded = ceil(mysql_num_rows($result) / 10);
for($x = 1; $x <= $rows_rounded; $x++){
echo 'Page '.$x.'';
}
But you need to consider detecting the current page, so if, for example, the current page was 3, it might be a good idea to test for that in your for loop and if echoing the 3rd link maybe add some extra class to enable you to style it.