SQL Keyword search - php

I am trying to create a search Function on my website using PHP and SQL.
I am trying to make it so that when i search for a keyword in it displays items matching the key word
This is my Database
If i was to search "rice chicken" it would return both Davida and roys, i would like it to only return Davids as it matches both words and not roys as roys only matches rice
Thos is my current code.
$search = $_GET['query'];
mysql_connect("localhost", "root", "") or die(mysql_error());
mysql_select_db("axamenu");
$query = mysql_query("SELECT * FROM menu WHERE CONTAINS(items,'$.search')");
if(mysql_num_rows($query) >= 1) {
while($a = mysql_fetch_array($query)) {
echo "<a href='".$a['profileurl']."'>".$a['restaurant']."</a><p>".$a['menutype']."</p><hr/>";
}
} else {
echo "Oh no! Nothing was found.";
}

You could make your query in this way
$where = '';
$string = "thi sdas asd";
$search = explode(" ",$string);
if(sizeof($search)>1)
{
$where = "1=1";
foreach($search=>$key as $val){
$where .= "or items like %".$val."%";
}
}
else
{
$where = "items like %".$search[0]."%"
}
$query = mysql_query("SELECT * FROM menu WHERE ".$where);
//rest of your code goes here
Note: Stop using deprecated and insecure mysql_*-functions. They have been deprecated since PHP 5.5 (in 2013) and were completely removed in PHP 7. Use MySQLi or PDO instead

If you only want davids result as "rice chicken",
you can split your string as rice and chicken and query as
SELECT * from menu WHERE items REGEXP 'rice' AND items REGEXP 'chicken'
you will get only one result
NOTE: using REGEXP can slow down result for bulk data retrieving

$search = $_GET['query'];
mysql_connect("localhost", "root", "") or die(mysql_error());
mysql_select_db("axamenu");
$query = mysql_query("SELECT * FROM menu WHERE
items LIKE '%".$search."%'");
if(mysql_num_rows($query) >= 1)
{
while($a = mysql_fetch_array($query))
{
echo "<a href='".$a['profileurl']."'>".$a['restaurant']."</a><p>".$a['menutype']."</p><hr/>";
}
}
else
{
echo "Oh no! Nothing was found.";
}

Try with this and let us if that works.
select * from table_name where items like 'rice%' or items like 'chicken%';

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.

how can i make more intelligent search by php and mysql

I have a table for places on database it contains two rows for title and description
I made a search by PHP and MYSQL like that
$select_place = $mysqli->query("SELECT * FROM places where title LIKE '%$searchname%' or description LIKE '%$searchname%'");
$num_place = $select_place->num_rows;
while ($rows_place = $select_place->fetch_array(MYSQL_ASSOC)){
$id_place = $rows_place ['id'];
$title_place = $rows_place ['title'];
$description_place = $rows_place ['description'];
echo "<p>{$title_place}</p><br>";
}
It works well, But, for example, if you search for the word tower if written in wrong way like twer or towr it doesn't work How can i make it more intelligent?
One good option is to include MySQL SOUNDEX() function:
SELECT
*
FROM
places
WHERE
title LIKE '%$searchname%'
OR description LIKE '%$searchname%'
OR SOUNDEX(title) = SOUNDEX('$searchname')
OR SOUNDEX(description) = SOUNDEX('$searchname')
This will match both towr and twer from your example.
More can be found here:
http://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_soundex
Note that:
This function, as currently implemented, is intended to work well with
strings that are in the English language only. Strings in other
languages may not produce reliable results.
i found very useful way to do it
here it is
$searchname = stringsafe($_GET['search']);
$searchname2 = explode(" ", $searchname);
$query = "SELECT * FROM places WHERE ";
foreach ($searchname2 as $each) {
$i++;
if($i == 1){
$query .= " title LIKE '%$each%'
OR description LIKE '%$each%'
OR SOUNDEX(title) = SOUNDEX('$each')
OR SOUNDEX(description) = SOUNDEX('$each')";
}else{
$query .= " OR title LIKE '%$each%'
OR description LIKE '%$each%'
OR SOUNDEX(title) = SOUNDEX('$each')
OR SOUNDEX(description) = SOUNDEX('$each')";
}
}
$select_place = $mysqli->query("$query limit 20");
$num_place = $select_place->num_rows;
if($num_place == 0){
echo "<div class='message-no'>No results</div>";
}
else{
while ($rows_place = $select_place->fetch_array(MYSQL_ASSOC)){
$id_place = $rows_place ['id'];
$title_place = $rows_place ['title'];
$description_place = $rows_place ['description'];
echo $title_place."<br>";
}

PHP Search Query is not working

I am trying to do a search on my website but for some reason my SELECT query is swapping the keyword and name of the column name when it is executed. Below is code for my query:
if(empty($_POST)=== false){
$output = '';
$error = '';
$input = $_POST['search_input'];
$i=0;
if($input){
$keyword = explode(" ", $input);
require ('core/dbconnection.php');
//If a user is logged in check if the user is Admin or Customer.
if(isset($_SESSION['userid'])){
if($admin == 1){
//enter admin code here
}
}else{
//If user is not logged in search items table only.
$search_items = "SELECT * FROM fyp_items WHERE ";
foreach($keyword as $k){
$i++;
if($i == 1){
$search_items .= "name LIKE $k OR description LIKE $k";
}else
$search_items .= " OR name LIKE $k OR description LIKE $k";
}
$item_qry = mysql_query($search_items)or die(mysql_error());
}
}else
$error = '<p class="pageerror">Please enter your search terms.</p>';
The $search_items is concatanating the search query which is then executed by $item_query .
So I searched for "conwerse" and echo'ed out the $search_itemsvariable I got the following:
http://awesomescreenshot.com/0302ft5mc3
However, when I run the query I get this mysql_error...
http://awesomescreenshot.com/0552ft6bb4
Seems like it swaps the keyword and column name when I run the query. My database tables are of type InnoDB> I would much appreciate your help!
First of all, dont use mysql_query as all mysql_ functions are deprecated. Use mysqli or pdo.
Second, escape your keywords with mysql_escape_string();, like
$k = mysql_real_escape_string($k);
Third, your query, when you echo it, needs to look like this:
SELECT * FROM fyp_items WHERE `name` LIKE 'conwerse' OR `description` LIKE 'conwerse';
There is more, but this should get you started.

adding further conditions to mysql loop

<?php
$query = $_GET['query'];
// gets value sent over search form
$min_length = 6;
// you can set minimum length of the query if you want
if(strlen($query) >= $min_length){ // if query length is more or equal minimum length then
$query = htmlspecialchars($query);
// changes characters used in html to their equivalents, for example: < to >
$query = mysql_real_escape_string($query);
// makes sure nobody uses SQL injection
$raw_results = mysql_query("SELECT * FROM cwnational WHERE (`postcode` = '$query') OR (`structure` LIKE '%".$query."%')") or die(mysql_error());
if(mysql_num_rows($raw_results) > 0){ // if one or more rows are returned do following
while($results = mysql_fetch_array($raw_results)){
echo "<p><h3>".$results['postcode']."</h3>".$results['structure']."</p>";
}
while($results = mysql_fetch_array($raw_results)){
if($results['structure'] = "National") {
echo "print national_table";
} else {
echo "print local_table";
}
}
else{ // if there is no matching rows do following
echo "No results";
}
}
else{ // if query length is less than minimum
echo "Minimum length is ".$min_length;
}
?>
</body>
I'm totally stumped now..
When I successfully match a $query, I want to use the 2nd part of the array which should be a column called structure and use that as a switch to either print table_local or table_national from the db.
re-wrote it after getting to grips with the correct approach,
if (empty($searchTerm)) {
echo "<h1>Empty search term</h1>";
$sqlQuery = false;
} elseif (strlen($searchTerm) < $minQueryLength) {
echo "<h1>Search term must be at least ".$minQueryLength." characters long.";
$sqlQuery = false;
} else {
if (strlen($firstPart) + strlen($secondPart) == 7) {
$sqlQuery = $mysqli->query("SELECT `postcode`, `structure` FROM `cwnational` WHERE `postcode` LIKE '".$firstPart." ".$secondPart."'");
} else {
$sqlQuery = $mysqli->query("SELECT `postcode`, `structure` FROM `cwnational` WHERE REPLACE(`postcode`, ' ', '') LIKE '".$searchTerm."%'");
}
}
if (is_object($sqlQuery) && $sqlQuery->num_rows >= 1) {
$resultArr = array();
while($row = $sqlQuery->fetch_assoc()) {
$resultArr[$row['postcode']] = array();
$priceQuery = $mysqli->query("SELECT `base_rate`, `commit_mbps` FROM `pricing` WHERE `structure` = '".$row['structure']."'");
if ($priceQuery->num_rows >= 1) {
while ($price = $priceQuery->fetch_assoc()) {
$resultArr[$row['postcode']][$price['commit_mbps']] = ((float)$price['base_rate'] + $transit[$price['commit_mbps']] ) + ( ( $transit[$price['commit_mbps']] + (float)$price['base_rate'] ) * ((float)$apiUser['margin']/100) ) ;
}
}
}
You're reading the result set twice. This will work for the first loop, but won't execute the second because you've already reached the end. If you need to read the results twice, use this:
mysql_data_seek ($raw_results , 0 )
immediately before the second loop to set the pointer to the beginning again.
Of course, you should be using mysqli...
what's going wrong now? I see you need to add an equals sign here:
if($results['structure'] == "National") {
note: double equals for php conditional
It also looks like you have an "else" coming out of a "while", that won't work. And you did this "while" loop twice, I'd combine them into a single "While":
while($results = mysql_fetch_array($raw_results)){

PHP - MYSQL fulltext search

I have a MYSQL full text search, matching against items in my database, which works great.
$select = "SELECT * from menu WHERE MATCH(item) AGAINST('$this->food') ";
From there I refine the query dependent on what the user wants to filter by. I have 2 filters, vegetarian and breadtype
if(isset($this->vegetarian)) {
echo $select .= " AND vegetarian='$this->vegetarian'";
}
if(isset($this->bread)) {
echo $select .= " AND bread='$this->bread'";
}
Which appends the fulltext statement, now this works perfectly, although my issue is that
if the user doesn't search anything (empty string) I want it to returns all results in the database.
if(empty($this->food)) { $select = "SELECT * from menu"; }
Which now means I can't append the $select statement with the above if statements, and would have to use a WHERE statement instead - but that would mean adding 2 extra if statements to compensate for that. Is there anyway for MYSQL to do it instead.
if(isset($this->vegetarian) && empty($this->food)) {
echo $select .= " WHERE vegetarian=$this->vegetarian";
}
You can simply use WHERE 1=1 and then append the rest. MySQL will simply ignore this part if there's no additional ANDs or ORs.
$select = "SELECT * from menu WHERE MATCH(item) AGAINST('$this->food') ";
if(empty($this->food)) {
$select = "SELECT * from menu WHERE 1=1"; // if food is empty we overwrite the $select variable
} else {
if(isset($this->vegetarian)) {
$select .= " AND vegetarian='$this->vegetarian'";
}
if(isset($this->bread)) {
$select .= " AND bread='$this->bread'";
}
}
Or am i missing something ?

Categories