How to make PHP makes this query - php

As I am learning PHP, naturally, I decided to create a search feature on my webpage. However I wanted to make mine more unique, so rather than using just a simple html input field as the 'search' field, I created two html select tags which allow the user to select two options and search based upon that. I managed to get the php to generate the search query, however it wasn't the sql query I wanted. My php code managed to generate a query hat looked like this: .com/results.php?option1=london&option2=car whereas ideally I want it to generate something like this: .com/results.php?combinedoptions=london+car
I've researched thoroughly into this and I hate to ask, what may be, a very simple question on this site.
$input = $_GET['input'];
$topic = $_GET['topic'];
$location = $_GET['location'];
$combined = $input . $topic . '' . $location;
$terms = explode(" ", $combined);
$query = "SELECT * FROM search WHERE ";
foreach ($terms as $each){
$i++;
if ($i == 1)
$query .= "keywords LIKE '%$each%'";
else
$query .= "OR keywords LIKE '%$each%'";
}

You would just split the incoming string. Here's a piece of code:
<?php
$combinedoptions = 'london+car';
$array = explode("+", $combinedoptions);
if (sizeof($array) != 2) { /*problem here*/ echo 'bad parameters'; return; }
$option1 = $array[0];
$option2 = $array[1];
?>
Just using the explode() method. Compiled code.

Related

Is there a way to use SQL query that would return results if values can be in any order?

My code let me perform search, as long as the order of the words is correct.
Let's say I'm searching for big dog, but I also want to search for dog big. It get more complicated with 3 or more words.
Is there a way to create a SQL query which would let me search through values with any order?
Only way I can think of this is by having multiple queries, where I change order of PHP variables manually...
<?php
if(isset($_GET['query']) && !empty($_GET['query'])) {
$query = $_GET['query'];
$query_array = explode(' ', $query);
$query_string = '';
$query_counter = 1;
foreach($query_array as $word) {
$query_string .= '%' . $word . (count($query_string) == $query_counter++ ? '%' : '');
}
$query = "SELECT * FROM pages WHERE Name LIKE '$query_string'";
$result = sqlsrv_query($cms->conn, $query);
while($row = sqlsrv_fetch_array($result)) {
extract($row);
echo ''.$Name.'<br>';
}
sqlsrv_free_stmt($stmt);
}
else {
//echo 'NO GET';
}
?>
You could assemble your conditions and check for each word on it's own:
$query_array = explode(' ', $query);
$queryParts = array();
foreach ($query_arra AS $value){
$queryParts[]="Name like '%".mysql_real_escape_string($value)."%'";
}
$searchString = implode(" AND ", $queryParts);
The Search string would now be Name like '%big%' AND Name like '%dog%' ... depending on how much search-keywords have been there.
I use the same approach very often, also when it is required that ALL keywords appear in at least ONE of the columns. Then you need one more loop to create the required AND conditions:
$search = "Big Dog";
$keywords = explode (" ", $search);
$columns = array("Name", "description");
$andParts = array();
foreach ($keywords AS $keyword){
$orParts = array();
foreach($columns AS $column){
$orParts[] = $column . " LIKE '%" . mysql_real_escape_string($keyword) . "%'";
}
$andParts[]= "(" . implode($orParts, " OR ") . ")";
}
$and = implode ($andParts, " AND ");
echo $and;
this would produce the query part (Name like '%Big%' OR description like '%Big%') AND (Name like '%Dog%' or description like '%Dog%')
So, it will find any row, where dog and big are appearing in at least one of the columns name or description (could also be both in one column)
Since your original querystring is something like %big%dog%, so I assume you are okay with matching big wild dog. In this case, you can just use the AND operator.
(Name LIKE '%big%" and Name LIKE '%dog%")
myisam supports full text search:
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
One thing you could look into is Full Text Search for ms sql server.
https://msdn.microsoft.com/en-us/library/ms142571.aspx
it's similar to a "search engine" in that it works off of an algorithm to rank results and even similar words (think thesaurus type lookups)
It's not exactly trivial to set up, but it's easy enough to find a tutorial on the subject and how to query from FTS (as the syntax is different than say LIKE '%big%dog%')
Here's a sample query from the page linked above:
SELECT product_id
FROM products
WHERE CONTAINS(product_description, ”Snap Happy 100EZ” OR FORMSOF(THESAURUS,’Snap Happy’) OR ‘100EZ’)
AND product_cost < 200 ;

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.

PHP Search multiple words in query against database table

I have a user query and a database. My database contains tables. What I am curious to know, is my method for querying the database. What I'm thinking is:
Separate the query into an array split by a space
Loop through each word and do a LIKE '%{$word}%' OR
Above that, just prior to each iteration, do an 'AND'
The problem is, its not working correctly. Its not dicing done to precise emails that match my queries. Here is my code:
$i=0;
$userQuery = $_POST['q']; // q = "Jonathan gmail"
$sql = "SELECT * FROM addresses WHERE ";
$parts = explode(' ',$userQuery);
$cnt=count($parts);
foreach($parts as $part){
$part = mysql_real_escape_string($part);
if($i!==$cnt-1){
$sql.="(
addresses.name LIKE '%".$part."%' OR
addresses.localpart LIKE '%".$part."%' OR
addresses.domain LIKE '%".$part."%'
) AND
";
} else {
$sql.="(
addresses.name LIKE '%".$part."%' OR
addresses.localpart LIKE '%".$part."%' OR
addresses.domain LIKE '%".$part."%'
)
";
}
$i++;
}
}
My question is whats wrong with this logic? It seems accurate.
First of all: This will break on a single word.
Second: This is everything else but safe from an SQL attack.
Now - how I'd do it
$parts = preg_split('/[\s,]+/',$userQuery);
$sql=array();
foreach($parts as $part) {
$part=mysql_real_escape_string($part); //Or whatever works with your DB access framework
$sql[]="(addresses.name LIKE '%$part%' OR addresses.localpart LIKE '%$part%' OR addresses.domain LIKE '%$part%')";
}
$sql=implode(' AND ', $sql);
$sql="SELECT * FROM addresses WHERE $sql";
hey something like this:
foreach($parts as $key => $part){
$part=mysql_real_escape_string($part);
$sql .= sprintf("(
addresses.name LIKE %s OR
addresses.localpart LIKE %s OR
addresses.domain LIKE %s
)", $part);
if ($key!=($cnt-1)) {
$sql .= " AND ";
}
}
Little notice, you're using $i variable before initializing it. Also maybe it will be a better way to use REGEXP. Something like:
// $search_terms = '%Jonathan%|%gmail%'
$sql = "addresses.name REGEXP $search_terms OR addresses.localpart REGEXP $search_terms OR addresses.domain REGEXP $search_terms";
More details on REGEXP

Passing multiple $_POST fields through MySQL search query

I have a search form with a possible 15 or so fields, however not all are required to carry out a search, for instance;
a user might search for a registered user in 'London' who works in 'Finance' but leave all other fields blank, such as $availability or $salary etc, so $_POST data may look something like:
$location = $_POST['location']; // Value - London
$sector = $_POST['sector']; // Value - Finance
$available = $_POST['available']; // Value - Any
$salary = $_POST['salary']; // Value - Any
Bearing in mind I may have another 12 or so 'Any' values from other fields, what is the best way to query the database (PHP/MySQL) to return results without looping through what would probably be dozens of queries.
To try and be a bit clearer, what i'd like is a query which would work something like (deliberate pseudo code):
SELECT * FROM table where location = 'location' AND if($availability !='Any') { available = '$available' } etc etc
Is something like this possible?
Or can I create a single string of all $_POST fields that !='Any' and then carry out a search on a row that contains all the words in the string (which I think would work in theory)?
I hope this makes sense to someone and you can point me in the right direction.
P.S. All $_POST is escaped and secured before interacting with database, just not included here :)
Try this:
$sql = "SELECT * FROM table where 1 ";
foreach ($_POST as $key => $post) {
if ($post != 'Any') {
$sql .= " AND $key = '$post' ";
}
}
// now you can run $sql against the database
Could you for argument sake collect all of the $_POST into a foreach($key=>$val) and then run the key through a switch or if statments that appends "AND x=x " to the statement?
Something like:
$sql = "SELECT * FROM table WHERE required='required'";
foreach($_POST as $key=>$val){
if(!empty($val)){ $sql .= " AND ".$key."='".$val"'"; }
}
Not sure if that works but in theory that is what i thought of first.
Thanks to those who offered answers, however I used the suggested answer found in the link above my question as it was clearer to me. Sample code pasted below FYI:
$tmp = "where ";
if($A and $A!="any" and $A!="not used")
$tmp .= "row1 = '".$A."'";
if($B and $B!="any" and $B!="not used")
$tmp .= "AND row2 = '".$B. "'";
if($C and $C!="any" and $C!="not used")
$tmp .= "AND row3 = '".$C."'";
$db_q = "Select * from table $tmp";
Thanks again, don't know where I'd be without SO.

Advance Searching, PHP & MySQL

I'm trying to create an Advanced Searching form that sort of look like this ;
http://img805.imageshack.us/img805/7162/30989114.jpg
but what should I write for the query?
I know how to do it if there is only two text box but three, there's too many probability that user will do.
$query = "SELECT * FROM server WHERE ???";
What should I write for the "???"
I know how to use AND OR in the query but lets say if the user only fill two of the textbox and one empty. If I write something like this ;
$query = "SELECT * FROM server WHERE model='".$model."' and brand='".$brand."' and SN='".$SN.'" ";
The result will return as empty set. I want the user can choose whether to fill one,two or three of the criteria. If I use OR, the result will not be accurate because if Model have two data with the same name (For example :M4000) but different brand (For example : IBM and SUN). If I use OR and the user wants to search M4000 and SUN, it will display both of the M4000. That's why it is not accurate.
If the user can decide how many criteria he wants to enter for your search and you want to combine those criteria (only those actually filled by the user), then you must dynamically create your SQL query to include only those fields in the search that are filled by the user. I'll give you an example.
The code for a simple search form could look like this:
$search_fields = Array(
// field name => label
'model' => 'Model',
'serialNum' => 'Serial Number',
'brand' => 'Brand Name'
);
echo "<form method=\"POST\">";
foreach ($search_fields as $field => $label) {
echo "$label: <input name=\"search[$field]\"><br>";
}
echo "<input type=\"submit\">";
echo "</form>";
And the code for an actual search like this:
if (isset($_POST['search']) && is_array($_POST['search'])) {
// escape against SQL injection
$search = array_filter($_POST['search'], 'mysql_real_escape_string');
// build SQL
$search_parts = array();
foreach ($search as $field => $value) {
if ($value) {
$search_parts[] = "$field LIKE '%$value%'";
}
}
$sql = "SELECT * FROM table WHERE " . implode(' AND ', $search_parts);
// do query here
}
else {
echo "please enter some search criteria!";
}
In the above code we dynamically build the SQL string to do a search ("AND") for only the criteria entered.
Try this code
<?php
$model="";
$brand="";
$serialNum="";
$model=mysql_real_escape_string($_POST['model']);
$brand=mysql_real_escape_string($_POST['brand']);
$serialNum=mysql_real_escape_string($_POST['serialNum']);
$query=" select * from server";
$where_str=" where ";
if($model == "" && $brand == "" && $serialNum == "")
{
rtrim($where_str, " whrere ");
}
else
{
if($model != "")
{
$where_str.= " model like '%$model%' AND ";
}
if($brand != "")
{
$where_str.= " brand like '%$brand%' AND ";
}
if($serialNum != "")
{
$where_str.= " serialNum like '%$serialNum%' AND ";
}
rtrim($where_str, " AND ");
}
$query.= $where_str;
$records=mysql_query($query);
?>
For those framiliar with mysql, it offers the ability to search by regular expressions (posix style). I needed an advanced way of searching in php, and my backend was mysql, so this was the logical choice. Problem is, how do I build a whole mysql query based on the input? Here's the type of queries I wanted to be able to process:
exact word matches
sub-string matches (I was doing this with like "%WORD%")
exclude via sub-string match
exclude via exact word match
A simple regexp query looks like:
select * from TABLE where ROW regexp '[[:<:]]bla[[:>:]]' and ROW
regexp 'foo';
This will look for an exact match of the string "bla", meaning not as a sub-string, and then match the sub-string "foo" somewhere.
So first off, items 1 and 4 are exact word matches and I want to be able to do this by surrounding the word with quotes. Let's set our necessary variables and then do a match on quotes:
$newq = $query; # $query is the raw query string
$qlevel = 0;
$curquery = "select * from TABLE where "; # the beginning of the query
$doneg = 0;
preg_match_all("/\"([^\"]*)\"/i", $query, $m);
$c = count($m[0]);
for ($i = 0; $i < $c; $i++) {
$temp = $m[1][$i]; # $temp is whats inside the quotes
Then I want to be able to exclude words, and the user should be able to do this by starting the word with a dash (-), and for exact word matches this has to be inside the quotes. The second match is to get rid of the - in front of the query.
if (ereg("^-", $temp)) {
$pc = preg_match("/-([^-]*)/i", $m[1][$i], $dm);
if ($pc) {
$temp = $dm[1];
}
$doneg++;
}
Now we will set $temp to the posix compliant exact match, then build this part of the mysql query.
$temp = "[[:<:]]".$temp."[[:>:]]";
if ($qlevel) $curquery .= "and "; # are we nested?
$curquery .= "ROW "; # the mysql row we are searching in
if ($doneg) $curquery .= "not "; # if dash in front, do not
$curquery .= "regexp ".quote_smart($temp)." ";
$qlevel++;
$doneg = 0;
$newq = ereg_replace($m[0][$i], "", $newq);
}
The variable $newq has the rest of the search string, minus everything in quotes, so whatever remains are sub-string search items falling under 2 and 3. Now we can go through what is left and basically do the same thing as above.
$s = preg_split("/\s+/", $newq, -1, PREG_SPLIT_NO_EMPTY); #whitespaces
for ($i = 0; $i < count($s); $i++) {
if (ereg("^-", $s[$i])) { # exclude
sscanf($s[$i], "-%s", $temp); # this is poor
$s[$i] = $temp;
$doneg++;
}
if ($qlevel) $curquery .= "and ";
$curquery .= "ROW "; # the mysql row we are searching in
if ($doneg) $curquery .= "not ";
$curquery .= "regexp ".quote_smart($s[$i])." ";
$qlevel++;
$doneg = 0;
}
# use $curquery here in database
The variable $curquery now contains our built mysql query. You will notice the use of quote_smart in here, this is a mysql best practice from php.net. It's the only mention of security anywhere in this code. You will need to run your own checking against the input to make sure there are no bad characters, mine only allows alpha-numerics and a few others. DO NOT use this code as is without first fixing that.
You have to provide $model, $brand, $serial which come from your search-form.
$query = "SELECT * FROM `TABLE` WHERE `model` LIKE '%$model%' AND `brand` LIKE '%$brand%' AND `serial` LIKE '%$serial%'";
Also take a look at the mysql doc
http://dev.mysql.com/doc/refman/5.1/en/string-comparison-functions.html
A basic search would work like this:
"SELECT * FROM server WHERE column_name1 LIKE '%keyword1%' AND column_name2 LIKE '%keyword2%' .....";
This would be case for matching all parameters.For matching any one of the criteria, change ANDs to ORs

Categories