How to use simpleHTMLdom parser with url that contains pagination? - php

I'm using simpleHTMLDom parser, it works very well with url like : http://someWebSite.com/page/1 suppose that i want to parse from page 1 to page 20 (for website that contain pagination).
i've tried (naively) this :
for($page = 1; $page <= 20; $page++){
$getHTML = file_get_html('http://website.com/page/'.$page);
}
It doesn't work (it get the last page and it parses it)
Any help please ??

for($page = 1; $page <= 20; $page++){
$getHTML = file_get_html('http://website.com/page/'.$page);
// <-- Do your stuff here
}
or
$getHTML = array();
for($page = 1; $page <= 20; $page++){
$getHTML[] = file_get_html('http://website.com/page/'.$page);
}
foreach($getHTML as $html){
// Do stuff with $html
}
You need to to something with the HTML befor you get the next one or store it and then to somethin with it.

Related

is there a difference if using a slash in the query string?

My webpage acts totally different if I use a slash before the ? in the URL.
(example.com/?p=1 instead of example.com?p=1 ignores the stylesheet for some reason)
is there a difference in the variable that my script gets using the GET method? And how do I make it so that it makes no difference if I use a slash or not?
this is some of my code
if (isset($_GET['p'])) {
$page = round ((int) mysql_real_escape_string($_GET["p"]));
if ($page > $tp or $page < 1) {
$page = 1;
goto a;
}
else goto a;
}
else $page = 1;

issue in selecting value in pagination

I think i am very near to my correct answer. I found one code on this forum like i wrote below.but it didn't work for me.Whats wrong with this code???
<?php
include("config.php");
$start = 0;
$per_page = 10;
$targetpage = "manual.php?id=$id"; // This is my target page
if(!isset($_GET['page'])){
$page = 1;
} else{
$page = $_GET['page'];
}
if($page<=1)
$start = 0;
else
$start = $page * $per_page - $per_page;
........................
.............................
.................?>
The answer which i saw contains id=42 in $targetpage = "manual.php?id=$id";But i don't understand why he used 42 there???
Then linking target page in next previous code as follows
<?php
if($page > 1){
$prev = $page - 1;
$prev = " <a href=\'$targetpage&page=$prev'>prev</a> ";
} else {
$prev = "";
}
if($page < $num_pages){
$next = $page + 1;
$next = " <a href=\'$targetpage&page=$next'>next</a> ";
}
else
{
$next = "";
}
echo $prev;
echo $next;
?>
But it gives me error like \'manual.php is not found..But i have this file.
just a guess, try to use:
$targetpage = "./manual.php?id=$id";
if it doesn't work then it means you are specifying the wrong URL to your manual.php page, try to find the correct URL
and id=42 it's an application specific parameter so it's related to that app so it's okay if you don't use it in your app.

XML pagination with PHP [duplicate]

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

Pagination do not correct display page numbers Codeigniter

My controller function
function test($start_from = 0)
{
$this->load->library('pagination');
$data = array();
$per_page = 3;
$total = $this->activity_model->count_by();
$config['base_url'] = base_url() . 'test';
$config['total_rows'] = $total;
$config['per_page'] = $per_page;
$config['uri_segment'] = 2;
$config['num_links'] = 2;
$config['use_page_numbers'] = TRUE;
$data['follow'] = $this->activity_model->get($per_page, $start_from);
$this->pagination->initialize($config);
$data['pagination'] = $this->pagination->create_links();
$this->load->view('front_end/test' ,$data);
}
my route :
$route['test'] = "user_activity/test";
$route['test/(:any)'] = "user_activity/test/$1";
model :
function get($limit,$start_from)
{
$sql = "SELECT * FROM user_follow LIMIT $start_from, $limit";
$query = $this->db->query($sql);
return $query->result_array();
}
Problem is that I have pagination 1,2,3,4,5.... and in every page I display 3 items. I want to do that in url it show my page numbers 1,2,3,4,5
When I click second page url show 3
When I click third page url show 6 and so on +3
is it possible, I spend hours for looking advice on internet but nothing as I understand [code]$config['use_page_numbers'] = TRUE;[/code] do what I need but in my case it still do not work.
Maybe you can advice any library ?
I managed to do this without modifying the class. The best way will be to make a copy of the pagination class, make your changes and use it. This way if you update CI, you won't lose the modification. Here is my solution without modifying the class.
First I want to say that using only the config option $config['use_page_numbers'] = TRUE will also do the trick but not entirely. The things I found out not working using only this option are the following:
if you try to edit the url bar pages manually it treats them like offset not like pages and also if you try to go back from page 2 to page 1 using the "prev" link it also treats the page number like an an offset.
The code:
$config['base_url'] = base_url('my/url/page');
$config['total_rows'] = count($this->my_model->get_all());
$config['per_page'] = 2;
$config['use_page_numbers'] = TRUE;
$config['uri_segment'] = 4;
//i'm looading the pagination in the constuctor so just init here
$this->pagination->initialize($config);
if($this->uri->segment(4) > 0)
$offset = ($this->uri->segment(4) + 0)*$config['per_page'] - $config['per_page'];
else
$offset = $this->uri->segment(4);
//you should modify the method in the model to accept limit and offset or make another function - your choice
$data['my_data'] = $this->my_model->get_all($config['per_page'], $offset);
This way
page = false (my/url) or (my/url/page) - basically if the 4th uri segment is false,
page = 0 (my/url/page/0),
and
page = 1 (my/url/page/1)
will all display the first page and then the other links will be working fine. I'm also validating the page e.g - if someone wants to enter (my/url/page/2323) this will throw an error and in the model you should check if the result is false and if it is the controller should show an error page or something. Hope this helps.
Make the following changes in Pagination class (/system/libraries/Pagination.php) so that it uses page numbers instead of offsets.
OLD (lines 146–153):
if ($CI->uri->segment($this->uri_segment) != 0)
{
$this->cur_page = $CI->uri->segment($this->uri_segment);
// Prep the current page - no funny business!
$this->cur_page = (int) $this->cur_page;
}
NEW:
Add ‘else’ option to if-statement to make sure default is; page = 1.
if ($CI->uri->segment($this->uri_segment) != 0)
{
$this->cur_page = $CI->uri->segment($this->uri_segment);
// Prep the current page - no funny business!
$this->cur_page = (int) $this->cur_page;
}
else
{
$this->cur_page = 1;
}
OLD (line 175):
$this->cur_page = floor(($this->cur_page/$this->per_page) + 1);
NEW:
Simply comment out this line so current page obeys controller/URI.
//$this->cur_page = floor(($this->cur_page/$this->per_page) + 1);
OLD (line 206):
$i = $uri_page_number - $this->per_page;
NEW:
Previous page should always be current page subtracted by 1.
$i = $uri_page_number - 1;
OLD (line 230):
if ($this->cur_page == $loop)
NEW:
URIs missing pagination should be considered page 1.
if ($this->cur_page == $loop || ($this->cur_page == 1 && $this->cur_page == $loop))
OLD (line 238–247):
if ($n == '' && $this->first_url != '')
{
$output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'">'.$loop.'</a>'.$this->num_tag_close;
}
else
{
$n = ($n == '') ? '' : $this->prefix.$n.$this->suffix;
$output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$n.'">'.$loop.'</a>'.$this->num_tag_close;
}
NEW:
Page URLs should use page numbers and not offsets.
if ($n == '' && $this->first_url != '')
{
$output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$loop.'">'.$loop.'</a>'.$this->num_tag_close;
}
else
{
$n = ($n == '') ? '' : $this->prefix.$n.$this->suffix;
$output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$loop.'">'.$loop.'</a>'.$this->num_tag_close;
}
OLD (line 256):
$output .= $this->next_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$this->prefix.($this->cur_page * $this->per_page).$this->suffix.'">'.$this->next_link.'</a>'.$this->next_tag_close;
NEW:
Next page should always be the sum of current page and 1.
$output .= $this->next_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$this->prefix.($this->cur_page + 1).$this->suffix.'">'.$this->next_link.'</a>'.$this->next_tag_close;
OLD (line 262):
$i = (($num_pages * $this->per_page) - $this->per_page);
NEW:
Last page should be the total number of pages.
$i = $num_pages;
Replace all the old lines with new lines. Make sure you do a backup of file before changing.
Hope this helps :)
EDIT:
You need to update your controller function test like :
function test($start_from = 0)
{
$this->load->library('pagination');
$data = array();
$per_page = 3;
$total = $this->activity_model->count_by();
$config['base_url'] = base_url() . 'test';
$config['total_rows'] = $total;
$config['per_page'] = $per_page;
$config['uri_segment'] = 2;
$config['num_links'] = 2;
$config['use_page_numbers'] = TRUE;
$start = $per_page * ($start_from-1);
$data['follow'] = $this->activity_model->get($per_page, $start);
$this->pagination->initialize($config);
$data['pagination'] = $this->pagination->create_links();
$this->load->view('front_end/test' ,$data);
}
Here i have added a new variable $start which is $per_page * ($start_from-1). Now pass this $start as argument to model.
What this do is multiply the number of items per page with (current page number -1 ) .This means if your items per page is 10 and you are on the second page the $start = 10 *(2-1) which gives 10. So your result will start from 10,20 and so one
Hope this helps :)
You can avoid php errors if someone manually entering the page number from the URL:
for example my/url/page/786
your result might not have anything to display for the query 786 , by default it will show you php error..to avoid this you can use:
if (isset($result)) {
$isArray = is_array($result) ? "YES" : "NO"; //check that result is an array or not as per your requirement.
if ($isArray == "YES") {
echo "show your stuffs here..";
}
else{
echo "display your message instead for php error here..";
}
}
hope this helps...
for query tweet me at twitter #sufiyantech

PHP from external anchor to internal

I have modified my project into a one page website type.
Part of the code is this:
for ($i = 1; $i <= $total_pages; $i++)
{
echo ''.$i.'';
}
I need that code above to work with an internal link for example:
From here:
echo ''.$i.'';
TO
echo ''.$i.'';
Here is the full source code:
$per_page = 6;
$result = mysql_query("SELECT * FROM mytable ORDER BY date DESC");
$total_results = mysql_num_rows($result);
$total_pages = ceil($total_results / $per_page);
if (isset($_GET['page']) && is_numeric($_GET['page']))
{
$show_page = $_GET['page'];
if ($show_page > 0 && $show_page <= $total_pages)
{
$start = ($show_page -1) * $per_page;
$end = $start + $per_page;
}
else
{
// error - show first set of results
$start = 0;
$end = $per_page;
}
}
else
{
// if page isn't set, show first set of results
$start = 0;
$end = $per_page;
}
// display pagination
echo '<strong>View Page:</strong> ';
echo '<div data-role="controlgroup" data-type="horizontal">';
for ($i = 1; $i <= $total_pages; $i++)
{
echo ''.$i.'';
//echo ''.$i.'';
}
echo '</div>';
I need to change this:
echo ''.$i.'';
so it's internal.
Short answer: This can't be done in PHP alone. You will need send AJAX requests to a PHP script that grabs the data.
Basically, this will involve creating some javascript that listens for any changes to the hash (that's the part after the #);
(function(window) {
var hash = window.location.hash;
setTimeout(function() {
if(window.location.hash !== hash) {
hash = window.location.hash;
//Grab and update page with ajax...
}
setTimeout(arguments.callee, 50);
}, 50);
})(window);
For AJAX basics, check W3Schools. And please, please respect the back button.
Without reloading the page:
foo
If you modify the query string in the link, the page will reload and jump to the anchor:
foo
Or with JQuery:
<script type="text/javascript">
$(document).ready(function(){
window.location.hash = 'my-anchor';
});
</script>

Categories