What is the best query for php-mysql search? - php

I have a search engine which is pretty straight forward. The query is below.
$sql = "SELECT * FROM events WHERE eventname LIKE '%".$_POST["search"]."%'
OR place LIKE '%".$_POST["search"]."%'
OR country LIKE '%".$_POST["search"]."%'
OR date LIKE '%".$_POST["search"]."%'
LIMIT 40";
But, Problem with this is this,
if I put the 'eventname' in search-box it is okay and it saws data from eventname column correctly. Or if I search only for place or country or date individually, it shows data correctly. But, if I search (FOR EXAMPLE) for both eventname and place together search results shows nothing. Using this query what are the changes I have to make to get it working?
Additionally I want to say that I have seen some of the query like "MATCH ... AGAINST". Though I don't want to use that, but if there are no other way what could be that "MATCH...AGAINST" query for this?
Here is my full code. They are straight forward. And I am working on a weird client's project and he want it to be like this and security is not a fact for him. So, you might notice some security issue which will be solved later. but the query first.
<?php
include_once("admin/connection/db.php");
$output = '';
$sql = "SELECT * FROM events WHERE eventname LIKE '%".$_POST["search"]."%'
OR place LIKE '%".$_POST["search"]."%'
OR country LIKE '%".$_POST["search"]."%'
OR date LIKE '%".$_POST["search"]."%'
OR date AND country LIKE '%".$_POST["search"]."%'
OR date AND place LIKE '%".$_POST["search"]."%'
OR date AND eventname LIKE '%".$_POST["search"]."%'
LIMIT 40";
$result = mysqli_query($db, $sql);
if(mysqli_num_rows($result) > 0) {
while($row = mysqli_fetch_array($result)) {
$output .= "<a class='search-result' href='".$row["link_pdf"]."'><li><i class='fa fa-trophy'> </i> ".$row["eventname"].'<br/>'.date('Y-m-d', strtotime($row["date"])).' || '.$row["place"].', '.$row["country"].'<img src="logos/'.$row["country"].'.png" width="30px" height="18px;" /></li></a>';
}
echo $output;
}else {
echo "<li>No Data Found Macthing Your Query</li>";
}
?>
Here is the link where you can check it directly
http://speed-timing2.6te.net/

I believe your search query term is for example "event_name place_name" and in this case your query will not work. You can use FULLTEXT search instead.
For example
at first set fulltext index for eventname, place, country field as those are string fields.
$sql = "SELECT * FROM (
SELECT *, MATCH (eventname, place, country) AGAINST ('".$_POST["search"]."' IN BOOLEAN MODE) AS score
FROM events
ORDER BY score DESC
) AS temp
WHERE temp.score>0 OR temp.date LIKE '%".$_POST["search"]."%'
";
Please check manual here http://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html

Related

Filter using PHP and MYSQL

I am an programming amateur, working on a small project of mine but i got stucked when I wanted make filters for my mysql output.
All works when I fill all search input fields and submit, correct filtered result appears. But when I leave one field out nothing shows up (only else command) as using AND condition. If I use OR and leave it empty it shows all result without caring what has been filled in the required fields.
Would there be any way how to show result even if one of the field stays empty? I tried to play with a code from different post here in stackoverflow but no luck yet as i am not really much experienced and cannot figure out how to use this inside of my code.
if(isset($_POST["profilename"]) && $_POST["profilename"] != "")
$sql .= " AND profilename = '". $_POST["profilename"] ."'";
Below here is my code, if you could have a look and suggest what i could edit so the filtering would be working.
<select class="form-control" id="Select1" name="departure">
<select class="form-control" id="Select2" name="destination">
<select class="form-control" id="Select3" name="layover">
...
<?php
include_once("connect.php");
if (isset($_GET['submit'])) {
$departure = mysqli_real_escape_string($connection, $_GET['departure']);
$destination = mysqli_real_escape_string($connection, $_GET['destination']);
$layover = mysqli_real_escape_string($connection, $_GET['layover']);
$result = mysqli_query($connection, "SELECT * FROM crud
WHERE departure LIKE '$departure%'
AND kam LIKE '$kam'
AND layover LIKE '$layover'
ORDER BY id DESC");
if($make = mysqli_num_rows($result) > 0){
while($r = mysqli_fetch_assoc($result)){
echo '<div style="display:block;"'.$r['departure'].'</div>';
echo '<div style="display:block;"'.$r['kam'].'</div>';
echo '<div style="display:block;"'.$r['layover'].'</div>';
//following code..
}
}else{
echo'<h4>No match found!</h4>';
print ($make);
}
mysqli_free_result($result);
mysqli_close($connection);
}
?>
For example: Filter Departure with Destination and leave Layover empty -> should return a result of desired Departure and Destination with ANY Layover.
or 2nd example: Fill Destination with Layover but leave Departure empty would result in desired search of Destination and Layover with ANY Departure.
Please let me know if its possible with my code and possibly how.
Thank you so much guys!!
You can check each input against an empty string in an OR condition within each of the different AND conditions.
"SELECT * FROM crud
WHERE ('$departure' = '' OR departure LIKE '$departure%')
AND ('$kam' = '' OR kam LIKE '$kam')
AND ('$layover' = '' OR layover LIKE '$layover')
ORDER BY id DESC"
This way, if one of the input parameters isn't given, the corresponding part of the condition will be interpreted as, for example, ('' = '' OR departure LIKE '$departure%') which will evaluate as true for every row since '' always equals '' regardless of the LIKE comparison.
A couple of notes - first, without any wildcard characters, your LIKE comparisons basically work like =, (e.g. kam LIKE '$kam' will match the same rows as kam = '$kam'). So either just use = or add some wildcards in order for those to be useful.
Second, consider using prepared statements instead of concatenating values into your SQL like this. The concatenation approach makes your code vulnerable to SQL injection and various annoying errors (even if you escape the strings).
something like this:
$result = mysqli_query($connection, "SELECT * FROM crud
WHERE (departure LIKE '$departure%' OR departure is null)
AND kam LIKE '$kam'
AND (layover LIKE '$layover' OR departure is null)
ORDER BY id DESC");
Let's put the "dont build your queries using user input" aside.
If you want to go that path, you could use conditionals to build the query step by step.
$query = "SELECT * FROM crud WHERE ";
if (!empty($departure)) {
$query .= "departure LIKE '$departure%' AND ";
}
if (!empty($destination)) {
$query .= "destination LIKE '$destination%' AND ";
}
if (!empty($layover)) {
$query .= "layover LIKE '$layover' AND ";
}
$query .= "1 ORDER BY id DESC";
You will end up with some alternatives in the $query string:
NOTHING SELECTED:
SELECT * FROM crud WHERE 1 ORDER BY id DESC
SOMETHING SELECTED:
SELECT * FROM crud WHERE departure LIKE '$departure%' AND layover LIKE '$layover' AND 1 ORDER BY id DESC
ALL SELECTED:
SELECT * FROM crud WHERE departure LIKE '$departure%' AND destination LIKE '$destination%' AND layover LIKE '$layover' AND 1 ORDER BY id DESC
This should cover it.
Have a good day

What is the correct MySQL syntax to retrieve data with multiple parameters

I am retrieving data from a database with php and MySQL as follows
$query = mysql_query("SELECT * FROM pictures WHERE (title LIKE '%$Search%' OR keywords LIKE '%$Search%') AND approved = 'YES' ORDER BY title ASC");
The query is correct and there are no errors and the query works fine for "title LIKE '%$Search%'" but the parameter "OR keywords LIKE '%$Search%'" is not retrieving data. The parameter "AND" also works correctly.
The keywords are stored in the database for example "pizza, restaurants, take away" but I don't see that is a problem.
My question is "What is the correct syntax for applying the "OR" parameter?
Remove the brackets around (title LIKE '%$Search%' OR keywords LIKE '%$Search%')
Those are generally used for subqueries.
$query = mysql_query("
SELECT * FROM pictures
WHERE title LIKE '%$Search%'
OR keywords LIKE '%$Search%'
AND approved = 'YES'
ORDER BY title ASC
");
https://dev.mysql.com/doc/refman/5.0/en/subqueries.html
Here is an example of a subquery, and pulled from the manual on MySQL.com:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
Edit:
Or try a different quoting method:
$query = mysql_query("
SELECT * FROM pictures
WHERE title LIKE '".%$Search%."'
OR keywords LIKE '".%$Search%."'
AND approved = 'YES'
ORDER BY title ASC
");
You could also try escaping your data:
$Search = mysql_real_escape_string($Search);
as an example. I don't know how you're assigning that variable.
phpMyAdmin test edit:
This is what I used inside phpMyAdmin:
SELECT * FROM table
WHERE col1 LIKE '%pizza%'
OR col2 LIKE '%pizza%'
AND col3 = 'YES'
ORDER BY col1 ASC
using pizza as the search keyword seeing that $Search will be based on the same keyword for you, where columns contain "large pizza" in one, and "pizza, take away, restaurants" in another.
Remember that, whatever you're using/assigning $Search to, must reside inside all your queried columns.
You may also want to make use of explode().
Here is an example pulled from https://stackoverflow.com/a/15289777/
<?php
$search = 'Gold Chain Shirt';
$bits = explode(' ', $search);
$sql = "SELECT name FROM product WHERE name LIKE '%" . implode("%' OR name LIKE '%", $bits) . "%'";
The above will generate this query:
SELECT name FROM product WHERE name LIKE '%Gold%' OR name LIKE '%Chain%' OR name LIKE '%Shirt%'
Sorry for taking some time but this is my working answer to my own question... not the prettiest syntax but it works without any string functions or explode functions. MySql can handle keywords quite well without any other functions being included:
$query = mysql_query("SELECT * FROM pictures
WHERE
title LIKE '%$Search%' AND featured IS NOT NULL AND streetview IS NOT NULL AND (id_user > '1') AND (status = '1')
OR
keywords LIKE '%$Search%' AND featured IS NOT NULL AND streetview IS NOT NULL AND (id_user > '1') AND (status = '1') ORDER BY title ASC");
Thank you all for your contributions

Run a query based on another query using mysql php

The code below searches my mysql database and comes back with postcodes like IG6,RM11,RM8,RM4,RM2,RM6,RM7,RM1,RM5 and a distance using a stored procedure. (All ok)
PROBLEM: With these results, I want to search another table in same database that may have job information with those Postcodes (probably using LIKE).
What's the best way to get this working? I have tried many examples (implode, arrays, etc)
Is one connection to database correct? How do I query the variable as it does come back with 2 columns, postcode and Distance. Should I split in an array (how?)
END PRODUCT: HGV Driver RM5, Cleaner RM5, Teacher RM5
(SELECT title FROM jobinfo WHERE location IN results from other query);
<?php
include ("conn.php");
$first="RM5";
$result = mysql_query("select outcode, GetDistance(Lat, Lon, (SELECT Lat from postcodes where outcode = '$first' limit 1),(SELECT Lon from postcodes where outcode = '$first' limit 1)) as Distance from postcodes having Distance < 3 order by Distance DESC;");
while($row = mysql_fetch_array($result))
{
echo ($row['outcode']) ;
}
// This returns postcodes
$resultb = mysql_query("SELECT title FROM jobinfo WHERE location IN ($results[outcode]) ");
while($row = mysql_fetch_array($resultb))
{
echo ($row['title']) ;
}
mysql_close($con);
?>
Please help.....any reference to join table needs full explanation as all so far don't help!
First Prepare the output into the clause:
in the first while loop:
while($row = mysql_fetch_array($result))
{
$array[] = $row['outcode'] ;
}
Then prepare the array for the IN clause:
foreach ($array as $a) {$clause.= "'$a',";}
$clause=substr($clause,0,-1)
Finally use the clause for the IN statement:
$resultb = mysql_query("SELECT title FROM jobinfo WHERE location IN ($clause) "
===== EDIT === LIKE statement
For like.. you need multiple like statement OR together.. Using SQL LIKE and IN together
Change the prepare clause code to this:
foreach ($array as $a) {$clause.= " location LIKE '%$a%' OR";}
$clause=substr($clause,0,-3)
AND the sql becomes:
$resultb = mysql_query("SELECT title FROM jobinfo WHERE $clause ");
Of course you will want to addin some more error checking.. think of the possible injection.
I think you're trying to do something like this answer MySQL LIKE IN()?
Also, please use parametrized queries How can I prevent SQL injection in PHP?

Search suggestion box inputs space in front of search query

We have a problem with our search suggestions. Everytime we click on a suggestion at our website, it puts a space in front of the search query, which causes the query to fail.
The code that we use for the suggestions is this:
$query = $db->query("SELECT DISTINCT productnaam FROM product WHERE merk LIKE '$queryString%' LIMIT 10");
if($query) {
// While there are results loop through them - fetching an Object (i like PHP5 btw!).
while ($result = $query ->fetch_object()) {
// Format the results, im using <li> for the list, you can change it.
// The onClick function fills the textbox with the result.
// YOU MUST CHANGE: $result->value to $result->your_colum
echo '<li onClick="fill(\''.$result->merk.' '.$result->productnaam.'\');">'
.$result->merk.' '.$result->productnaam.''.'</li>';
}
} else {
echo 'ERROR: There was a problem with the query.';
Try out with trim()
$queryString = trim($queryString);
The trim() function removes whitespaces and other predefined characters from both sides of a string.
try the trim() function as Sameera Thilakasiri specified below and also update your query to something like "SELECT DISTINCT productnaam FROM product WHERE merk LIKE '%$queryString%' LIMIT 10" The percent sign on both sides will ensure that your query will select records that contain your input as opposed to records that start with your input.
bellow is some further explanation on the SQL LIKE condition that might help you out
// This query will look for records that start with "sa"
select * from table where name like 'sa%'
// This query will look for records that contain "sa"
select * from table where name like '%sa%'
// This query will look for records that end with "sa"
select * from table where name like '%sa'
hope that helps!

Multiple SQL Searches - OR Command

My users can search for an order by an address right now. What I would like to do is let them be able to search with multiple criteria. Let them search by address, city, state, etc etc.
I have tried using the following code, but it doesn't seem to work.
$sql = ("SELECT order_number, sitestreet FROM `PropertyInfo` WHERE `sitestreet` LIKE '%$street%' OR `sitecity` LIKE '%$city%' AND `user` LIKE '$user'");
$result = mysql_query($sql);
I don't think it's reading the value in $user cause it displays all orders for all users.
How can I make it possible to search for an order using multiple serach values?
Thank you!
Wrap your OR statements in parenthesis so it forms one top-level condition, the user is the other top-level condition:
$sql = '
SELECT
`order_number`,
`sitestreet`
FROM
`PropertyInfo`
WHERE
(
`sitestreet` LIKE "%'.$street.'%" OR
`sitecity` LIKE "%'.$city.'%"
) AND
`user` = '.$user;
Also note, you want a direct match to the user column, use = instead of LIKE. I am assuming that $user is a numeric ID...
How about trying like
$sql = ("SELECT order_number, sitestreet FROM PropertyInfo WHERE (sitestreet LIKE
'%$street%' OR sitecity LIKE '%$city%') AND user LIKE '$user'");
AND has a higher order of precedence than OR (see http://dev.mysql.com/doc/refman/5.0/en/operator-precedence.html for details). You need to wrap your OR statement in parentheses so it get evaluated as one statement, before the AND statement.
SELECT order_number, sitestreet
FROM `PropertyInfo`
WHERE (`sitestreet` LIKE '%$street%' OR `sitecity` LIKE '%$city%')
AND `user` LIKE '$user'
Try:
$sql = ("
SELECT order_number, sitestreet
FROM `PropertyInfo`
WHERE (`sitestreet` LIKE '%$street%'
OR `sitecity` LIKE '%$city%')
AND `user` LIKE '$user'");
You should group the ORs together. The way it is written I believe it is reading it as 'if Street matches, ignore any other conditions (OR), otherwise both city and user must match.
Also G molvi's point is good, unless you're looking for a pattern match, go with =
HTH

Categories