How to create multiple word search? SQL - php

We have made a search field where you can search for ingredients and find recipes.
For now you can only type in 1 ingredient:
if (isset($_POST['search'])) {
$searchquery = $_POST['search'];
$query = mysql_query("SELECT * FROM opskrifter WHERE id IN
(SELECT opskrifterid FROM ingredienser WHERE ing_name IN ('$searchquery'))") or die("search failed");
We want to be able to search for multiple ingredients in the same search field by seperating the ingredients with a "," or something like this.
Is there a simple way to make that happen ?
EDIT:
We tried to use explode like this without succes.
$searchTerms = explode(' ', $searchquery);
$searchTermBits = array();
foreach ($searchTerms as $term) {
if (!empty($term)) {
$searchTermBits[] = "ing_name '$term'";
}}
...
$result = mysql_query("SELECT * FROM opskrifter WHERE id IN (SELECT * FROM WHERE ".implode(' AND ', $searchTermBits)));
Thanks! :)

You could simply get the user to type in his values comma-separated, the the input would be almost in the right syntax for the query. You just have to add semicolons around the values because you search for a string in your table.
You can use PHP's str_replace()-Function:
$vals = $_POST['search'];
$valsFormatted = "'" . str_replace(",", "','", $vals) . "'";
In this code, you replace all the commas of the input with the comma plus semicolons before and behind them in orderto wrap all values of the input with semicolons. You also have to add one at the beginning and at the end of the string. Replace the first comma in the function above with the char you want your users to separate the values with.
After that, you can simply change your query to the following:
$query = "SELECT * FROM opskrifter WHERE id IN
(SELECT opskrifterid FROM ingredienser WHERE ing_name IN ('$valsFormatted'))";
Please also be informed, that your code like this is vulnerable for SQL Injections! Check out this link to learn how to prevent this.

A simple statement like this would work:
$array = implode("','",explode($_POST['search'], ","));
$query = mysql_query("SELECT * FROM opskrifter WHERE id IN (SELECT opskrifterid FROM ingredienser WHERE ing_name IN ({$array}))") or die("search failed");
First explode your search, then implode it (might not even need to do so). After that make sure the array gets used as the 'in' operator as a string/array.
For more information about this, you could read this question: PHP/MySQL using an array in WHERE clause
The working copy from my local machine was this;
$_POST['search'] = "0, 1, 2";
$array = implode ( "','", explode ( ",", $_POST['search'] ) );
$query = mysql_query("SELECT * FROM users WHERE id IN ('$array')") or die(mysql_error());
var_dump ( $array );
var_dump ( $query );
var_dump ( "SELECT * FROM users WHERE id IN ('$array')" );
var_dump ( mysql_fetch_array ( $query ) );
which actually did return users, so if we would take this example and change it to your code, it would be (the query, at least):
$query = mysql_query("SELECT * FROM opskrifter WHERE id IN (SELECT opskrifterid FROM ingredienser WHERE ing_name IN ('$array'))") or die(mysql_error());
Do take note of the changed $array variable too.

First you need to convert the text coming from the search field to array with:
$string = $_POST['search'];
$array = explode( '"' , $string);
So if you put in the search: test"hello"hi
the array will be:
1 => test,
2 => hello,
3 => hi
After that, you need to use the SQL format:
WHERE column_name IN (value1,value2,...)
So you need to change the array we have created to a string with this format:
$string = implode(',',$array);
So the echo of $string will be:
test,hello,hi
and SQL will be :
WHERE column_name IN ($string)

Related

PHP: How to insert array value into mysql statement

i have this array and get it from from an url. this array is member id that i need to pass to mysql.
$member_id = $_GET['member_id'];
the array like this : Array ( [0] => 1269 [1] => 385 )
how can i transfer this array into my mysql statement and make , become AND :
$answer_sql = mysql_query("SELECT tna_category. * , tna_question. *, tna_answer. *
FROM tna_category, tna_question, tna_answer
WHERE tna_category.section_id = '$section_id1'
AND tna_question.id = tna_answer.question_id AND tna_question.category_id = tna_category.id
AND tna_answer.member_id = ['1269' , '385']
ORDER BY tna_answer.question_id");
should i put bracket?..
in this part : tna_answer.member_id = Array or $member_id
As others have said, you can use IN() but you are apparently open to SQL injection attacks as it is. You need to do this:
$escaped_ids = array_map('mysql_real_escape_string', $member_ids);
Or, if they are surely all integers
$escaped_ids = array_map('intval', $member_ids);
Then, you can write your query like:
$query = "SELECT tna_category. * , tna_question. *, tna_answer. *
FROM tna_category, tna_question, tna_answer
WHERE tna_category.section_id = '" . mysql_real_escape_string($section_id1) . "'
AND tna_question.id = tna_answer.question_id
AND tna_question.category_id = tna_category.id
AND tna_answer.member_id IN (".implode(",", $escaped_ids).")
ORDER BY tna_answer.question_id";
Never, never, never put unescaped values in your query.
Also, you should not be using the mysql_ functions anymore. Please consider using the mysqli_ functions instead.
First split the array value, get no. of rows in the array value and pass the value one by one into the query by using for or foreach loop.
try this
$member_id = $_GET['member_id'];
If you're already getting comma seprated values then there's no need to use explode function just use implode function in database query.
$member_id = explode(",", $member_id);
and then
answer_sql = mysql_query("SELECT tna_category. * , tna_question. *, tna_answer. *
FROM tna_category, tna_question, tna_answer
WHERE tna_category.section_id = '$section_id1'
AND tna_question.id = tna_answer.question_id AND tna_question.category_id = tna_category.id
AND tna_answer.member_id IN (".implode(",", $member_id).")
ORDER BY tna_answer.question_id");
the explode function create array it depends on you explode value with comma OR space and then implode mean join these values with comma OR space.
for more detail explode and implode.
you can use IN clause of mysql like this
$your_array = array("0"=>"1269", "1"=>"385");
$in_text = implode(",", $your_array);
$sql = "SELECT tna_category. * , tna_question. *, tna_answer. *
FROM tna_category, tna_question, tna_answer
WHERE tna_category.section_id = '$section_id1'
AND tna_question.id = tna_answer.question_id
AND tna_question.category_id = tna_category.id
AND tna_answer.member_id IN ($in_text)
ORDER BY tna_answer.question_id";

PHP MySQL REGEX match search

I want to fetch data from my user table which tag id stored like :
userid tagid
5036 |4815|324|
1396 |1393|4567|
2676 |2669|345|2345|
I have a tagid array like as
Array
(
[0] => 4815
[1] => 4567
)
Need to fetch data using mysql where in condition like "select * from user where tagid in ()".
Is there any preg_match function for it?
Suggest you loop the array and append using likes, something like:
$tags = array(2,4,6);
$query = 'select * from user where ';
foreach($tags as $i=>$tag) {
if ($i>0) $query.=' or '; // or and?
$query.='tagid like "%|'.$tag.'|%"';
}
Because you're having to use a wildcard on both sides of the match they would both be about the same (I think regexp may be a little faster in your case).
The problem is that you may have false positives because of the chance of a substring in your searches because of the lack of normalization.
An example:
Searching for %15%
Matches 915,15,150,215790
Because of this, you should actually do this, since in this case, LIKE would not be sufficient unless you always wrap the IDs in the pipe characters |:
<?php
$ids = array('115','215','225');
foreach($ids as $id){
$query = "select * from user where tagid regexp '[^0-9]*$id[^0-9]*'";
}
?>
At which point you could use this:
<?php
$ids = array('115','215','225');
foreach($ids as $id){
$query = "select * from user where tagid like '%|$id|%'";
}
?>
You can do it like that:
$tagid = array(4815,4567);
$query = "select * from user where tagid regexp '\|("
. implode("|", $tagid) . ")\|'";
then you obtain:
select * from user where tagid regexp '\|(4812|4567)\|'

Select using a php variable with more than one ID

I have a PHP variable that looks like this for example:
$list = "12|421|466|501|1042|"
What I wanna do is to match each number with a field in my database table.
SELECT * FROM tableName WHERE id = any of the numbers in $list
Which is the simplest way to do this?
Use this SQL:
SELECT * FROM tableName WHERE id IN (12, 431, 466, 501, 1042)
Use explode(), implode() to convert your list to a comma separated list.
Use IN like this:
"SELECT * FROM tableName WHERE id IN (".str_replace('|', ',', substr($list, 0, -1)).")"
use replace to replace | into comma and remove the last | so that you could get the string in
correct format
$list = str_replace('|',',',$list);
$query = "select * from table where ID in ($list)";
SELECT * FROM table WHERE id LIKE '%$list%'
not so sure | is a good seperator. maybe u should try setting it into an array.
guy below got it!!!
This should work:
<?php
$list = "12|421|466|501|1042|";
$items = array_filter(
array_map( 'trim', explode( "|", $list ) ),
function( $item ) {
return $item != ''; // filter empty values.
}
);
$query = 'SELECT foo FROM bar WHERE id IN ( ' . implode( ', ', $items ) . ' );';
echo $query;
if you wan the combined result you can use IN statement like:
SELECT * FROM tableName WHERE id IN ( $cat = str_replace("|", "," , $list) )
Or if you want the separate results you have to iterate through all the values.
$array = preg_split( "\\|" , $list );
foreach ($array as $value) {
SELECT * FROM tableName WHERE id = $value
}
SELECT * FROM tableName WHERE id IN ('.str_replace('|',',',$list).');
it will repalce all | with , and then you can run query with IN condition to get desired records..

WHERE id=(array)

The code below only outputs single line(there are 2 in database that should be outputed).
I think that problem is in id=$data[id] since data1 is array instead of single value.I hoped that while will fix that but it doesnt look too good...
$results1 = mysql_query("SELECT * FROM keywords WHERE keyword='$search' ORDER BY (relevant-irrelevant) DESC");
$data1=mysql_fetch_array($results1);
$results2=mysql_query("SELECT * FROM searchengine WHERE id='$data1[id]'");
while($data2=mysql_fetch_array($results2))
First, isolate your ids, looping to get all of the results:
$ids = array();
while ( $data1 = mysql_fetch_array($results1) ) {
$ids[] = $data1['id'];
}
Then, convert your $ids array into a string. An easy way to do this is via implode():
$results2=mysql_query(
"SELECT * FROM searchengine WHERE id IN (" . implode(',', $ids) . ")"
);
Maybe I´m missing something, but how can $data1['id'] be an array? it´s probably an integer and perhaps a string, but it's not an array. $data1['id'] is a single value; the value of field id in the keywords table
I think you just need to put curly quotes around the variable:
$results2=mysql_query("SELECT * FROM searchengine WHERE id='{$data1[id]}'");
or even better:
$results2=mysql_query("SELECT * FROM searchengine WHERE id=" . (int) $data1['id']);
If id is an integer that is.
And of course if the first query returns more than 1 result, you will have to loop through them as well.
Couldn't you just select the entire thing in one query?
SELECT *
FROM keywords k
searchengine s
WHERE k.keyword='$search'
AND k.id = s.id
$results1 = mysql_query("SELECT * FROM keywords WHERE keyword='$search' ORDER BY (relevant-irrelevant) DESC");
$data1=mysql_fetch_array($results1);
//VERY DANGEROUS TO USE USER INPUT
$in = join(',',$data1['id']);
$results2=mysql_query("SELECT * FROM searchengine WHERE id IN ({$in})");
while($data2=mysql_fetch_array($results2))
You can't pass array as condition. You should:
a. do a for(each) loop in the $data1 array and perform next actions
b. implode the array and search with IN. Example:
$commaSeparated = implode(",", $data1);
$results2=mysql_query('SELECT * FROM searchengine WHERE id IN ('.$commaSeparated.'));
mads.ohm is correct about combining the two queries into a single query.
As for your problem with only getting one return value, your while loop is just overwriting the contents of $data2 each time through.
You could write something like this instead:
$i = 0;
$data2 = array();
while ($row = mysql_fetch_array($results2)) {
$data2[$i] = $row;
$i++;
}
In this case, $data2 is declared as an array, and each iteration of the while loop adds a row from the database to the array.

WHERE var = "$name" AND var = "$name"

I am trying to select stories for my mysql database Where the author variable is equal to a list of names.
I basically have a list of names that I want use in determining what stories to pull.
$names = "name1 name2 name3 name4"
$get_stories = mysql_query("SELECT * FROM glnce_stories WHERE author = '$names' ORDER BY id DESC");
I know that this isn't the right way to do but I was looking for some solutions on how I might be able to break that list up so I can have it pull from the authors in that $names variable.
Thanks!
If you aren't able to change the format of the $names variable, this should work:
$names = 'name1 name2 name3 name4';
$names = '"' . implode('","', explode(' ', $names)) . '"';
$get_stories = mysql_query('SELECT * FROM glnce_stories WHERE author IN(' . $names . ') ORDER BY id DESC');
comma separate the names and then
use "WHERE author in (" . $names . ")";
You should use WHERE field in (list) like this:
$names = "'name1', 'name2', 'name3', 'name4'";
$get_stories = mysql_query("SELECT * FROM glnce_stories WHERE author in ($names) ORDER BY id DESC");
So, your query should look something like this: SELECT * FROM glnce_stories WHERE author in ('Bob', 'Steve', 'Andrey', 'Mike', 'Jenna')
Rewrite your code as follows:
$names = "name1 name2 name3 name4";
$names = "'".implode ("','", array_map('mysql_real_escape_string', explode(' ', $names))."'";
$get_stories = mysql_query("SELECT * FROM glnce_stories WHERE author in ($names)");
You can use FIND_IN_SET() for that if you want to be lazy. You will just have to turn your names list into a comma-separated string:
$names = "name1,name2,name3,name4";
mysql_query("SELECT * FROM stories WHERE FIND_IN_SET(author, '$names')"
That's maybe easier than a list of OR conditions or preparing a proper string list for an IN clause. (You can _real_escape_string the whole comma separated list, instead of each name.)

Categories