I'm trying to create a pagination for my PDO query. I cant figure it out. I've tried numerous google searches, but nothing that will work for me. [I probably didn't search hard enough. I'm not sure]
This is my code:
$sql2 = "SELECT * FROM comments WHERE shown = '1'ORDER BY ID DESC";
$stm2 = $dbh->prepare($sql2);
$stm2->execute();
$nodes2= $stm2->fetchAll();
foreach ($nodes2 as $n1) {
echo "text";
}
I want to be able to limit 10 comments per page, and use $_GET['PAGE'] for the page.
Something that I tried
$sql2 = "SELECT * FROM comments WHERE shown = '1'ORDER BY ID DESC";
$stm2 = $dbh->prepare($sql2);
$stm2->execute();
$nodes2= $stm2->fetchAll();
$page_of_pagination = 1;
$chunked = array_chunk($nodes2->get_items(), 10);
foreach ($chunked[$page_of_pagination] as $n1) {
echo "text";
}
If someone could help out, I appreciate it.
You need to limit the query that you are performing, getting all values from the database and then limiting the result to what you want is a bad design choice because it's highly inefficient.
You need to do this:
$page = (int)$_GET['PAGE']; // to prevent injection attacks or other issues
$rowsPerPage = 10;
$startLimit = ($page - 1) * $rowsPerPage; // -1 because you need to start from 0
$sql2 = "SELECT * FROM comments WHERE shown = '1' ORDER BY ID DESC LIMIT {$startLimit}, {$rowsPerPage}";
What LIMIT does:
The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants
More information here: http://dev.mysql.com/doc/refman/5.7/en/select.html
Then you can proceed getting the result and showing it.
Edit after comment:
To get all the pages for display you need to know how many pages are there so you need to do a count on that SELECT statement using the same filters, meaning:
SELECT COUNT(*) as count FROM comments WHERE shown = '1'
Store this count in a variable. To get the number of pages you divide the count by the number of rows per page you want to display and round up:
$totalNumberOfPages = ceil($count / $rowsPerPage);
and to display them:
foreach(range(1, $totalNumberOfPages) as $pageNumber) {
echo '' . $pageNumber . '';
}
Related
I have a simple php code below
$sql_items = "SELECT id FROM item_masterfile"; /* this query has 7000 rows */
$result_items = mysqli_query($con,$sql_items);
while ($row_items = mysqli_fetch_row($result_items)) {
$sql_qty = "SELECT qty FROM inventory WHERE id = ".$row_items[0];
/* rest of the code here */
}
}
this is working but due to a lot data my server cannot handle it and other queries took long to respond. how can I fix this? My target here is like batch select? to prevent clogged?
What I see in the process is a lot of select waiting to initiate.
How can I fix this?
try with batches using limit and offset like below
$offset = $i * 5000; // $i is run batch number .. 1, 2, 3 etc in the foreach() loop.
if ($i == 0) {
$offset = "";
}
$result_items="SELECT id FROM item_masterfile LIMIT 5000 OFFSET $offset;";
The code in your question shows that there is one_to_one or one_to_many relation between tables, so using pagination and join statement would resolve the problem.
Check below code hope to be helpful
$sql = "
SELECT im.id, i.qty
FROM item_masterfile AS im
JOIN inventory AS i ON
im.id = i.item_masterfile_id
LIMIT $offset, $limit
";
$result_items = mysqli_query($con,$sql);
you can set $offset and $limit dynamically in your code and go on ...
Instead of using the loop and providing id in there, you should collect all the ids in an array and then pass all of them to the query in one go using the IN operator.
Example: SELECT qty FROM inventory WHERE id IN (1,2,3,4,5). By doing this you can avoid loop and you code will not exit with timeout error.
OR
You can achieve the same using a subquery with your main query
Example: SELECT qty FROM inventory WHERE id IN (SELECT id FROM item_masterfile)
Try with follow step:
get result of first query and get id values like (1,2,3,4,...)..
and out side where clause execute second query with WHERE condition IN clause
Like
$sql_items = "SELECT id FROM item_masterfile"; /* this query has 7000 rows */
$result_items = mysqli_query($con,$sql_items);
while ($row_items = mysqli_fetch_row($result_items)) {
$ids[] = $row_items['id'];
}
$sql_qty = "SELECT qty FROM inventory WHERE id IN ".$ids;
/* rest of the code here */
}
I have a DB table with 100-200k records and I need to optimize it. For example, if a user want to search the term car, he will get around 25k results.
I would like to offer him just let's say 500 newest results, but how to do that? I know I have to use LIMIT, but I am not sure, how to "group" just the newest 500 rows.
For making a better picture how I am fetching data from database now, here's a little snippet:
$search = mysql_real_escape_string(searched_query($_GET['skill']));
$q = "...long sql query...";
echo $q;
$result = mysql_query($q);
$items = 30; // number of items per page.
$all = $_GET['a'];
$num_rows = mysql_num_rows($result);
if($all == "all"){
$items = $num_rows;
}
$nrpage_amount = $num_rows/$items;
$page_amount = ceil($num_rows/$items);
$page_amount = $page_amount-1;
$page = mysql_real_escape_string($_GET['p']);
if($page < "1"){
$page = "0";
}
$p_num = $items*$page;
// Query that you would like to SHOW
$result = mysql_query($q." ORDER BY published DESC LIMIT $p_num , $items");
Thank you in advance!
By ordering by published DESC you have already ordered the list from newest to oldest. So if you apply the limit of 500, it will automatically only fetch the newest 500 rows...
So Mysql will order first, and then apply the limit.
Use ORDER BY in the query. Have a look here for more details
I have a section on my website where users can post comments. Just above these comments I have 4 links - Oldest, Newest, Top Rated and Worst Rated. Currently I have 4 different pages for each of these links.
oldest.php - sorts the comments by date and time ascending
newest.php - sorts the comments by date and time descending
top.php - sorts the comments depending on how many likes they have
worst.php - sorts the comments depending on how many dislikes they
have
They are all being sorted with a mySQL statement such as
$sql = "SELECT * FROM comments ORDER BY date DESC, time DESC LIMIT $offset, $rowsperpage";
I'm just wondering is there any way to order these comments by using just one page instead of having 4 different pages?
Any help would be greatly appreciated.
Yes, you pass the sort column and direction in the URL.
$type = 'new'; // default order
$cols = array('old', 'new', 'worst'); // array with possible options columns, to prevent SQL injection
if (in_array($_GET['type'], $cols) {
$type = $_GET['type'];
}
$order = (strtolower($_GET['order']) == 'asc')?'ASC':'DESC'; // again - to prevent bad data
$sql = "SELECT * FROM comments ORDER BY {$type} {$order}, time DESC LIMIT $offset, $rowsperpage";
If you have different queries, just use a switch() statement, and change the query accordingly for each type of order.
// use the same order as before
switch ($_GET['type']):
case 'old':
$sql = " ... ";
break;
// more options
default:
// default can be used for the most common option, for example when you first enter the page with no type argument in the URL
break;
One more thing - to generate the URLs you can use this:
$cols = array('old', 'new', 'worst'); // you can make this array a config variable
$order = array('asc', 'desc');
foreach ($cols as $col) {
foreach ($order as $ord) {
echo "<a href='index.php?type={$col}&order={$ord}'>".ucwords($col). ' ' . ucwords($ord)"</a>";
}
}
This will print all the types with all the possible orders. You should play around with this, you can do some neat, dynamic stuff.
Sure you can have single page to manage that.
Instead of 4 pages, you can have single page
comments.php
and then you can pass GET parameter like below for 4 links
comments.php?type=oldest
comments.php?type=newest
comments.php?type=top
comments.php?type=worst
Then on comments.php you can put conditional statement like below:
$order_by = "ORDER BY date DESC, time DESC"; // Default order
if(isset($_GET["type"]) && $_GET["type"] == "newest")
$order_by = "ORDER BY date DESC, time DESC";
elseif(isset($_GET["type"]) && $_GET["type"] == "oldest")
$order_by = "ORDER BY date, time";
elseif(isset($_GET["type"]) && $_GET["type"] == "top")
... put your order by here ...
elseif(isset($_GET["type"]) && $_GET["type"] == "worst")
... put your order by here ...
Then use below $sql
$sql = "SELECT * FROM comments ".$order_by." LIMIT $offset, $rowsperpage";
Hi I am trying to display my users data over pages
Here is my code:
//Run a query to select all the data from the users table
$perpage = 2;
$result = mysql_query("SELECT * FROM users LIMIT $perpage");
It does display this the only two per page but I was wondering how you get page numbers at the bottom that link to your data
here is my updated code
$result = mysql_query("SELECT * FROM users"); // Let's get the query
$nrResults=mysql_num_rows($result); // Count the results
if (($nrResults%$limit)<>0) {
$pmax=floor($nrResults/$limit)+1; // Divide to total result by the number of query
// to display per page($limit) and create a Max page
} else {
$pmax=floor($nrResults/$limit);
}
$result = mysql_query("SELECT * FROM users LIMIT 2 ".(($_GET["page"]-1)*$limit).", $limit");
// generate query considering limit
while($line = mysql_fetch_array( $result ))
{
?>
error
Parse error: syntax error, unexpected $end in E:\xampp\htdocs\Admin.php on line 98
In order to do this you also need to use the offset value in your SQL Statement, so it would be
SELECT * FROM users LIMIT $offset, $perpage
Example:
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
Then to get the links to put on the bottom of your page you would want to get a count of the total data, divide the total by the per page value to figure out how many pages you are going to have.
Then set your offset value based on what page the user clicked.
Hope that helps!
Update:
The unexpected end most likely means that you have an extra closing bracket } in your code which is causing the page to end and still has more code after it. Look through your code and match up the brackets to fix that. There are a few other issues in the code sample you pasted.
$result = mysql_query("SELECT * FROM users" ); //Note if you have a very large table you probably want to get the count instead of selecting all of the data...
$nrResults = mysql_num_rows( $result );
if( $_GET['page'] ) {
$page = $_GET['page']
} else {
$page = 1;
}
$per_page = 2;
$offset = ($page - 1) * $per_page; //So that page 1 starts at 0, page 2 starts at 2 etc.
$result = mysql_query("SELECT * FROM users LIMIT $offset,$per_page");
while( $line = mysql_fetch_array( $result ) )
{
//Do whatever you want with each row in here
}
Hope that helps
You can then use the nrResults number to figure out how many pages you are going to have... if you have 10 records and you are displaying 2 per page you would then have 5 pages, so you could print 5 links on the page each with the correct page # in the URL...
Use requests ! http://php.net/manual/en/reserved.variables.request.php
if (((isset($_GET['page'])) AND (is_int($_GET['page']))) {
$perpage = $_GET['page'];
}
$result = mysql_query("SELECT * FROM users LIMIT $perpage");
...
Link http://yourwebsite.com/userlistforexample.php?page=3
or
http://yourwebsite.com/userlistforexample.php?somethingishere=21&page=3
how can i check current number in mysql where....
my query is
$aid = 16;
$get_prev_photo = mysql_query("SELECT * FROM photos WHERE album_id='$aid' AND pic_id<'$picid' ORDER BY pic_id LIMIT 1");
$get_next_photo = mysql_query("SELECT * FROM photos WHERE album_id='$aid' AND pic_id>'$picid' ORDER BY pic_id LIMIT 1");
while i am getting current photo with following query
$photo = mysql_query("SELECT * FROM photos WHERE pic_id='$picid' LIMIT 1");
and getting total photos in album with following query
$photos = mysql_query("SELECT * FROM photos WHERE album_id='$aid'");
$total_photos = mysql_num_rows($photos);
now i want to check where i am and show it as Showing 1 of 20, showing 6 of 20 and so on...
now i want to check where i am actually...
i think you are referring to pagination, which can be achieved using LIMIT and OFFSET sql
decide the number of results you want per page, then select that many
create links like:
View the next 10
and dynamically change those every time
queries look ~like~
$offset=$_GET['view'];
SELECT * FROM table WHERE `condition`=true LIMIT 5 OFFSET $offset
this translates roughly as
select 5 from the table, starting at the 10th record
This is bad:
$photos = mysql_query("SELECT * FROM photos WHERE album_id='$aid'");
Because it grabs all the fields for the entire album of photos when all you really want is the count. Instead, get the total number of photos in the album like this:
$result = mysql_query("SELECT count(1) as total_photos FROM photos
WHERE album_id='$aid'");
if ($result === false) {
print mysql_error();
exit(1);
}
$row = mysql_fetch_object($result);
$total_photos = $row->total_photos;
mysql_free_result($result);
Now you have the count of the total number of photos in the album so that you can set up paging. Let's say as an example that the limit is set to 20 photos per page. So that means that you can list photos 1 - 20, 21 - 40, etc. Create a $page variable (from user input, default 1) that represents the page number you are on and $limit and $offset variables to plug into your query.
$limit = 20;
$page = $_POST['page'] || 1; // <-- or however you get user input
$offset = $limit * ($page - 1);
I'll leave the part where you code the list of pages up to you. Next query for the photos based on the variables you created.
$result = mysql_query("SELECT * FROM photos WHERE album_id='$aid'
ORDER BY pic_id LIMIT $limit OFFSET $offset");
if ($result === false) {
print mysql_error();
exit(1);
}
$photo_num = $offset;
while ($row = mysql_fetch_object($result)) {
$photo_num++;
$pic_id = $row->pic_id;
// get the rest of the variables and do stuff here
// like print the photo number for example
print "Showing photo $photo_num of $total_photos\n";
}
mysql_free_result($result);
I'll leave better error handing, doing something with the data, and the rest of the details up to you. But that is the basics. Also I did not check my code for errors so there might be some syntax problems above. To make a single photo per page just make $limit = 1.