How to php pagination of results obtained from this database - php

I am a beginner in php.
I visualize in my html page the results obtained with this php code, and now I want to paginate the results and limit your search to 6 items per page. How can I get this? My php code is as follows:
<?php
$k = $_GET['k'];
$terms = explode(" ", $k);
$query = "SELECT * FROM table_name WHERE ";
$i = 0;
foreach ($terms as $each){
$i++;
if ($i == 1)
$query .= "keywords LIKE '%$each%' ";
else
$query .= "OR keywords LIKE '%$each%' ";
}
// connect
mysql_connect("hostname","databaseUser","databasePassword");
mysql_select_db("databaseName");
$query = mysql_query($query);
$numrows = mysql_num_rows($query);
echo "<p><strong>Totale: {$numrows} risultati trovati</strong></p></br>";
if ($numrows > 0){
while ($row = mysql_fetch_assoc($query)){
$id = $row['id'];
$title = $row['title'];
$description = $row['description'];
$keywords = $row['keywords'];
$link = $row['link'];
$date = $row['date'];
$caption = $row['caption'];
echo "<h4><a href='$link'>$title</a></h4>";
echo "<em>$description</em></br></br>";
echo "$caption</br>";
echo "$link</br></br>";
echo "<em>$date</em></br></br>";
}
}
else
echo "NO result found for \"<p><strong>$k</strong></p>\"";
// disconnect
mysql_close();
?>

Pagination is a problem that most of us have tried to solve over the years.
You can build your own library to do this but you'll almost definitely be re-inventing the wheel and might not spot/handle some of the special cases.
If you're using a framework I'd suggest using the built in paginator, if not you could look at using something like http://pear.php.net/package/Pager which is a PEAR package.

You need to add a page variable into your code. The easiest way to to this is via $_GET, just like you grabbed keywords, so your url should look something like this:
foo.php?k=keywords%20here&p=1
Where p is the current page number.
Then you just need to add a limit to your search results so that you only grab 6, and the correct 6 at that. Something like this:
$query .= ' LIMIT '.(6*($pageNum - 1)).' 6';
This statement tells SQL to start at the first entry for the given page, and grab 6 results. We subtract 1 from the page number so that page 1 starts at entry 0 instead of entry 6.
The result of this code:
page | statement | Rows Grabbed
---------------------------------
1 | LIMIT 0 6 | 1-6
2 | LIMIT 6 6 | 7-12
3 | LIMIT 12 6 | 13-18
---------------------------------
and so on...
You might need to check that $_GET['p'] is an integer before you put it in $pageNum, so that you don't run into runtime issues trying to multiply a string by 6.
If you ever want to change the results per page, simply replace the 6's in that statement with the desired number of results per page, e.g.
$query .= ' LIMIT '.($numResults*($pageNum - 1)).' '.$numResults;
That way you can set your desired number of results with another variable, say $_GET['n'] or something similar, and have even better control.
EDIT:
You should probably add error checking:
$pageNum = (is_numeric($_GET['p']) ? intval($_GET['p']) : 1);
which says if GET[p] is numeric, set pageNum to the integer value of GET[p]. Otherwise, set pageNum to 1.
Also, You have a few errors in the way that you put variables into strings. There are two ways to join a variable into a string, you can either use double quotes and curly braces, like so:
$string = "this string has {$variable} in it";
Or you can concatenate with periods, using either single or double quotes likes so:
$string = 'this string has ' . $variable . " in it";
You have this problem in your foreach loop when you append the query, and also further down where you output your results.

Related

Search Query not works Properly : Php Like Query

<?php
include"configration.php";
?>
<?php
$query = $_GET['query'];
$min_length = 1;
//echo $query;exit();
if (strlen($query) >= $min_length) { // if query length is more or equal minimum length then
//echo "success";exit();
$query = htmlspecialchars($query);
$query = mysqli_real_escape_string($conn, $query);
$sql = "SELECT * FROM table2
WHERE title LIKE '%".$query."%' order by date DESC";
$raw_results = mysqli_query($conn, $sql) or die(mysql_error());
if (mysqli_num_rows($raw_results) > 0) { // if one or more rows are returned do following
while ($res = mysqli_fetch_array($raw_results)) { ?>
<?php echo $res['title'] ?> // Place where result comes ..
<?php }
}
}
?>
This is code works fine but search in this way
For Example Title is: you are vary nice boy but lazy
When I search by:
You are vary ............. result shows ..
vary nice boy ............. result shows ..
vary lazy, or boy lazy or vary lazy .. result not shows ..
Plz some one help me in this and how to show searched query in title ..
<title> Searched Query ...</title>
LIKE '%boy lazy%' will show the Of the cases where anything can be before boy lazy and anything can be after boy lazy, but boy lazy will be together.
In your case, one approach can be, you can explode your $query, and then use multiple LIKE queries to create sql query. Example:
<?php
//$conn = mysqli_connect("localhost","your user","your pass","db");
$query = $_GET['query'];
$min_length = 1;
//echo $query;exit();
if (strlen($query) >= $min_length) { // if query length is more or equal minimum length then
//echo "success";exit();
$query = htmlspecialchars($query);
$query = mysqli_real_escape_string($conn, $query);
$searchKeys = explode(' ',$query);
$sql = "SELECT * from table2 where title ";
foreach ($searchKeys as $key) {
$sql.= "LIKE '%".$key."%' AND title ";
}
$sql = substr($sql, 0, -10);
//$sql.="ORDER BY date DESC;";
$raw_results = mysqli_query($conn, $sql) or die(mysql_error());
if (mysqli_num_rows($raw_results) > 0) { // if one or more rows are returned do following
while ($res = mysqli_fetch_assoc($raw_results)) {
echo $res['title']."\n";
}
}
}
When you search title LIKE "%vary lazy%", you will get records that contain the string "vary lazy" preceeded and followed by any other or no character sequences. If you want to match strings that contain the words - I should better say, the character sequences - "vary" and "lazy" in that specific order you should use:
title LIKE "%vary%lazy%"
However, this will also match "varylazy", "varying lazytown characters".
Assuming you generally intend to use queries as you mentioned, i.e. each word is separated by a space character and you want to see if those words appear in a text in specifically that order, you could write something like this:
$query = $_GET["query"];
$query = '%'.str_replace(' ', '%', $query).'%';
//... MySQL stuff
Please be aware that the code above is very specific to your needs. I wouldn't use it as a general purpose approach for processing query strings, e.g. having multiple spaces between words would result in multiple consequent % in your SQL query - I'm not even sure if that is allowed. However, under the constraints described, this code should work just fine.

Issues using between, min and max

I have created a catalog with a block of years search function for characters and the years I've assigned to them. So anything from 1940-1949 would be in the 1940's block of time, and so on. I'm using a href to group these timeframes.
<?php
$sql = "SELECT * FROM catalog";
$displayby = $_GET['displayby'];
$displayvalue = $_GET['displayvalue'];
if($displayby && $displayvalue){
$sql = "SELECT * FROM catalog WHERE $displayby LIKE '$displayvalue'";
}
if($displayby == 'year'){
$min = $_GET['min'];
$max = $_GET['max'];
$sql = "SELECT * FROM catalog WHERE year BETWEEN '$min' AND '$max'";
}
//$result = mysqli_query($con,$sql);
$result = mysqli_query($con,"SELECT * FROM catalog WHERE year BETWEEN '$min' AND '$max'");
while($row = mysqli_fetch_array($result)){
$name = $row['name'];
$filename = $row['filename'];
$cid = $row['cid'];
echo "\n<div class=\"holder\">";
echo "<img src=\"thumbs/$filename\">";
echo "$name<br />\n";
echo "</div>";
}
?>
With this href to only bring up certain characters within those years:
40's Villans<br/>
However they are showing up in the years prior - it might be 1945 as a set date for the character but they only appear in 1930's link.
What am i doing wrong?
Edit : here is the table
BETWEEN ... AND .... can be used for integers and strings. so:
BETWEEN 1 AND 3
Will be true for 1, 2 and 3. But:
BETWEEN 'a' AND 'c'
Will be true for 'a', 'b' and 'c'.
http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_between
You've put quotes around your numbers, turning them into strings. So the comparison is done on the characters, not the numbers.
Removing the quotes should make it work.
$result = mysqli_query($con,"SELECT * FROM catalog WHERE year BETWEEN $min AND $max");
But as said by others, there are a lot of other problems with the code. This mistake is a symptom of someone who doesn't really know what they're doing. Why not start at the beginning, and grab a good book. Read it. Do the examples. Experiment. It can take years to become a fluent programmer. (This is meant as an ecouragement, not critizm.)
instead of using between you can also use the following statement for getting the desired data as following
$sql = "SELECT * FROM catalog WHERE year >= '$min' AND year <='$max'";
and in phpmyadmin you can run the query to make sure that you are getting the correct data ,and after that you can check your code where you are displaying it
i hope it help's you..

PHP MySQL query returning NULL

I have a MySQL table that looks like this:
index | tag | posts
-------------------------
1 | cats | 9,10
2 | a cat | 9,10
3 | kitty | 9,10
4 | meow | 9,10
I am trying to just return the row that matches a search query.
I passed the search parameter using a simple ?search=cats.
This is the PHP that I'm using:
$search = $_GET['search'];
$query = mysql_query("SELECT * FROM tags WHERE tag = '$search'");
echo(mysql_num_rows($query));
$result = mysql_fetch_array($query);
$print = $result['posts'];
echo($print);
However the mysql_num_rows($query) prints 0 and the $print returns NULL. I can check it with ($print == ""), it evaluates to TRUE and mysql_num_rows($query) returns 4.
I tried setting the search query to something that wasn't in the table and it retuned FALSE as expected. I also tried removing the WHERE tag = '$search' and it returns the table like it should.
Is there something I'm overlooking?
Edit
Took everyone's advice and the code I'm using now is:
$search = mysql_real_escape_string($_GET['search']);
var_dump($search); //prints string(4) "cats" just like it should
$queryText = "SELECT * FROM tags WHERE tag = '%".$search."%'";
echo($queryText); //SELECT * FROM tags WHERE tag = '%cats%'
$query = mysql_query($queryText) or die(mysql_error()); //no error
$rows = mysql_num_rows($query); //this returns 0 and I know it should match 1 row
echo('rows: '.$rows);
$result = mysql_fetch_array($query);
$print = $result['posts'];
echo($print); //empty
Still have the same problem. The mysql_query is retuning NULL instead of the row or FALSE if it doesn't match.
(in the future I will use the mysqli API, but I would like to finnish this project in mysql. thanks for your suggestions and advice)
Try this code now.
Remeber when you want to debug something in PHP the faster way is var_dump not echo. Also you should avoid mysql_api because they are deprecated, use PDO instead PDO on PHP.net
var_dump($_GET); // Just for debuggin if as something
$search = $_GET['search'];
$query = mysql_query("SELECT * FROM tags WHERE tag = '".mysql_real_escape_string($search)."'");
// echo(mysql_num_rows($query));
$result = mysql_fetch_array($query);
var_dump($result);
//$print = $result['posts'];
//echo($print);
Ok so after referring to the above edit you made, here is the solution
Use "LIKE" instead of "=" when using wildcard "%"
So your query now should be
$queryText = "SELECT * FROM tags WHERE tag LIKE '%" . $search . "%'";
[I created the exact same db on my local system and ran the same code you gave, After making the above changes, It runs as expected]
$search = $_GET['search'];
echo $select_query="SELECT * FROM tags WHERE tag = '".mysql_real_escape_string($search)."'";
$query = mysql_query($select_query);
echo(mysql_num_rows($query));
while($result = mysql_fetch_array($query))
{
print_r($result);
}
Note:
$search = $_GET['search'];
$query = mysql_query("SELECT * FROM tags WHERE tag = '$search'");
That is very dangerouse: It allow sql incersion code to your database. You must always escape all what you get from the client.
$search = mysql_real_escape_string($_GET['search']); //It require open database connection.
Note2:
mysql_query is obsolete, use mysqli instead ;-)
Answer:
If you have not answer, you probable has an error in an other part.
Try
//1) Look if your search has a correct value
var_dump($search);
//2) Replace the query with (just for debugging):
$query = mysql_query("SELECT * FROM tags WHERE tag = 'cats';");
You may also use "tag like '%cats%'" if you want a more flexible search.
If you remove the WHERE tage = '$search', it cannot return the table like it should because your mysql_fetch_array is not in a while loop... but that aside...
// make sure before you execute the code to check that $_GET['search'] is not empty
// start with escaping the search-value (for mysql-injection)
$search = msyql_real_escape_string($_GET['search']);
// changed the query so it searches for tags containing the search value.
// if you would have records with tags "blue cat" and "red cat" it shows them both
// when searching for "cat"
$query = mysql_query("SELECT * FROM tags WHERE tag LIKE '%".$search."%'");
// put the number of rows in a var
$num = mysql_num_rows($query);
// check this var if it's not 0
if ($num != '0'){
while ($row = mysql_fetch_array($query){
echo $row['posts'];
// etc...
}
} else {
// 0 rows found
echo "nothing found";
}

PHP link only passing part of a mysql result

OK i have a php link which is made up of several variables
<a href=\year.php? manufacturer='.$manufacturer.'&fuel_type='.$fuel_type.'&model_type='.$model_type.'>'.$model_type.'</a>
The whole code is really long as it has a lot of pagination, so i will just include the basic query and the loop part.
$query1 = "SELECT Distinct model_type from $tableName where manufacturer='$manufacturer' AND fuel='$fuel_type' LIMIT $start, $limit";
$result = mysql_query($query1);
And then the bottom part where i get and show the results.
$count = 0;
$max = 2;
while($row = mysql_fetch_array($result))
{
$model_type = $row['model_type'];
$count++;
echo '<td class="manu"><div align="center">'.'<a href=\year.php? manufacturer='.$manufacturer.'&fuel_type='.$fuel_type.'&model_type='.$model_type.'>'.$model_type.'</a>'.'</div></td>';
if($count >= $max){
//reset counter
$count = 0;
//end and restart
echo '</tr><tr>';
}
}
now this works fine except when i take the mode type variable from the database it shows as 1 series, however when it is passed in this link it only gets the 1 and doesn't pick up the series.
Thanks
try to pass it like:
'.urlencode($model_type).'
Try To access it on next page with urldecode($_REQUEST['$model_type'])
I am not shure but you probably have a missing encoding Problem.
try this:
'.$model_type.'
Its url_encoding the values so your url doesnt get broken by ',",spaces and so on.
additional Hint:
Enclose your URL with " or ' so you do not get problems at the end.

Pagination while using a GET variable

I have had a difficult time paginating the code below. I think it has to do with passing the GET variable $find on to the next page.
Anyway, how would I paginate the code below, so that the table below shows only 100 rows per page?
Thanks in advance,
John
<?php
ob_start();
session_start();
$find = strip_tags($_GET['find']);
$illegal = array("'", ".", "/", "\"", ";", "{", "}", "[", "]", "\\", "''", "'''", "''''", "'''''", "\\\\", "\\\\\\", "\\\\\\\\");
$find = str_replace($illegal, '', $find);
$find = trim ($find);
$find = strtolower($find);
$find = stripslashes($find);
$_SESSION['find'] = $find;
?>
<?
if ($searching =="yes")
{
if ($find == "")
{
session_write_close();
header("Location:http://www.site.com/index.php");
exit;
unset($_SESSION['find']);
}
mysql_connect("mysqlv10", "username", "password") or die(mysql_error());
mysql_select_db("database") or die(mysql_error());
$find = mysql_real_escape_string($find);
$result=mysql_query("SHOW TABLES FROM database LIKE '$find'")
or die(mysql_error());
if(mysql_num_rows($result)>0){
while($table=mysql_fetch_row($result)){
print "<p class=\"topic\">$table[0]</p>\n";
$r=mysql_query("SELECT * , votes_up - votes_down AS effective_vote FROM `$table[0]` WHERE site != '' ORDER BY effective_vote DESC");
print "<table class=\"navbar\">\n";
while($row=mysql_fetch_array($r)){
$effective_vote = $row['votes_up'] - $row['votes_down'];
print "<tr>";
print "<td class='sitename'>".'<a type="amzn" category="products" class="links2">'.$row['site'].'</a>'."</td>";
print "<td class='votes'>".'<span class="votes_count" id="votes_count'.$row['id'].'">'.number_format($effective_vote).'</span>'."</td>";
print "<td class='ballot'>".'<span class="button" id="button'.$row['id'].'">'.''.vote.''.'</span>'."</td>";
}
print "</tr>\n";
}
print "</table>\n";
}
?>
You have to use LIMIT in your query to tell the database how many rows you want and where to start from.
Pass along a parameter that tells the script that you want another chunk of the results and not just the first batch.
So for the link you can pass along the page parameter:
example.com/results.php?page=2
Where page= will tell the script what page you want to return.
Then you'll want to LIMIT the number of rows returned each time so that you have consistent paging.
$results_cnt = 100; //--rows you want per page of results
Now in your script you'll check to see if the page variable has been set. If not, default the start row to return from the first. But as you want to return different pages/sets of results, a little math is needed in order to start at the proper row.
if(isset($_GET["page"]) //--see if the variable is even there
{
$page_num = (int)$_GET["page"]; //--forcing it to always be an integer
$start_row = $results_cnt * ($page_num - 1);
/* --
what happens:
($results_cnt currently at 100)
on page one (page=1), start at row 0
math: 100 * (1 - 1) = 0
on page two (page=2), start at row 100
math: 100 * (2 - 1) = 100
on page three (page=3), start at row 200
math: 100 * (3 - 1) = 200
etc.
*/
}
else
$start_row = 0;
Now, having set the correct starting row, adjust the SQL query to use the variables like so:
$r = mysql_query("SELECT *, votes_up - votes_down AS effective_vote
FROM `$table[0]`
WHERE site != ''
ORDER BY effective_vote DESC
LIMIT $start_row, $results_cnt");
Every time you hit the page it will be checking to see if $_GET["page"] is there. If not, then display from the first row. If it is, do the maths and work out how many rows to pass over and show the next page of.
you need to use
LIMIT (<pagenumber*amount of records you want to display>,< amount of records you want to display >)
in your SQL statement

Categories