Search for different tables with multiple words - php

I have a form
<form action="buscar.php" method="GET">
<input type="text" name="q" />
</form>
And my page where they show the results
<?php
require_once 'meekrodb.php';
$q = $_GET['q'];
$results = DB::query("SELECT * FROM product_description WHERE description like '%$q%'");
foreach ($results as $row) {
echo $row['name']."<br>";
}
?>
For example I have these phrases in description:
My car is big and green
My house is small and green
When I look for green, the 2 results come out, but if I look for a green house nothing comes out.
The problem is that I have to search for continuous text to work for example... My house is small...
How can I improve this query? Thank you

Try to explode GET variable.Or you can try to play with CONCAT
Explode
$q = $_GET['q'];
$word_array = explode(" ",$q);
$sqlnames="SELECT * FROM product_description WHERE";
$count = 0;
foreach($word_array as $value){
if($count == 0){
$sqlnames .= " description LIKE '" . $value ."'";
}
else{
$sqlnames .= " OR description LIKE '" . $value ."'";
}
$count = 1;
$sqlnames .= " OR description LIKE '" . $value ."'";
}
$sqlnames .="LIMIT 20";
CONCAT
(something like that)
$results = DB::query("SELECT * FROM product_description WHERE description LIKE '%$q%' OR description LIKE '%$q%' OR CONCAT(description, ' ', description ) LIKE '%$q%' LIMIT 20");
I have not tested this, but you can try to play.

Related

Foreach mysql select result

I want to create a search field like if I search "Spinach, Watermelon", it will explode the input by ",", and run MySQL search database. That means the SQL will run as
SELECT * FROM table
WHERE vegetable LIKE '%Spinach%' OR fruits LIKE '%Spinach%'
SELECT * FROM table
WHERE vegetable LIKE '%Watermelon%' OR fruits LIKE '%Watermelon%'
My database table data looks something like this :
id Vegetable fruits
----------------------
1 Spinach Apple
2 Cucumber Orange
3 Spinach Watermelon
The result of each id only can come out once.
<php>
$keywords = trim($_REQUEST['keyword']);
$keyword = explode(",", $keywords);
foreach($keyword as $keys=>$select)
{
$sql = "SELECT * FROM table WHERE vegetable LIKE '%keyword %' OR fruits LIKE '%keyword %'";
$result = mysqli_query($conn, $sql);
while ($rs = mysqli_fetch_array($result))
{
$vege = $rs["vegetable"];
$fruits = $rs["fruits"];
}
}
<html>
<form method=post>
<input type="text" class="form-control" placeholder="SEARCH..." value="<?=$keywords?>">
</form>
</html>
If you are open to using REGEXP with an alternation instead of LIKE, then here is a straightforward approach:
$keywords = trim($_REQUEST['keyword']);
$keywords = preg_replace("/,\s*/", "|", $keywords);
$where = "[[:<:]](" . $keywords . ")[[:>:]]";
$sql = "SELECT * FROM table ";
$sql .= "WHERE vegetable REGEXP '" . $where . "' OR fruits REGEXP '" . $where . "'";
$result = mysqli_query($conn, $sql);
while ($rs = mysqli_fetch_array($result)) {
$vege = $rs["vegetable"];
$fruits = $rs["fruits"];
}
Assuming you passed in the keywords search string "Spinach, Watermelon", the above script would generate this query:
SELECT *
FROM table
WHERE
vegetable REGEXP '[[:<:]](Spinach|Watermelon)[[:>:]]' OR
fruits REGEXP '[[:<:]](Spinach|Watermelon)[[:>:]]';
Honestly the best approach here would be to use LIKE or REGEXP with a prepared statement. If you do choose to use my approach, then you absolutely should sterilize the incoming CSV string to make sure it has only alphanumeric characters, comma, and whitespace in it.
Hitting database in for loop is not a good approach, You can build you query like this:
<?php
$keywords = trim($_REQUEST['keyword']);
$keyword = explode(",", $keywords);
$sqlWhere = '';
foreach($keyword as $keys=>$select)
{
$sqlWhere .= "LIKE '%$select%' OR";
}
$sqlWhere = rtrim($sqlWhere, "OR");
$sql = "SELECT * FROM table " . $sqlWhere;
$result = mysqli_query($conn, $sql);
while ($rs = mysqli_fetch_array($result))
{
$vege = $rs["vegetable"];
$fruits = $rs["fruits"];
}
?>
Try this, It will print your records must.
<php>
$keywords = trim($_REQUEST['keyword']);
$keyword = explode(",", $keywords);
for($i=0; $i<count($keyword); $i++)
{
$sql = "SELECT * FROM table WHERE vegetable LIKE '%" . $keyword[$i] . "%' OR fruits LIKE '%" . " . $keyword[$i] . " . "%'";
$result = mysqli_query($conn, $sql);
$rs = mysqli_fetch_array($result);
echo "<pre>"; print_r($rs); exit;
}
?>
<html>
<form method=post>
<input type="text" class="form-control" placeholder="SEARCH..." value="<?=$keywords?>">
</form>
</html>
I think your probelm is "*The result of each id only can come out once.".
So better make one Query:
$keywords = trim($_REQUEST['keyword']);
$keyword = explode(",", $keywords);
$where = [];
foreach($keyword as $keys)
{
$where[] = "vegetable LIKE '%".$keys." %' OR fruits LIKE '%".$keys." %'";
}
$sql = "SELECT * FROM table ".(empty($where) ? '' : implode(' OR ', $where));
so you have one query an one result set.
Dont forgett to escape your keywords.

Regular Expression mysql with AND operator

I had create a search field and if i search "Spinach, Watermelon", it will explode the input by ",", and run MySQL search database. That means the SQL will run as
SELECT * FROM table WHERE
(vegetable LIKE '%Spinach%' OR fruits LIKE '%Spinach%') AND (vegetable LIKE '%Watermelon%' OR fruits LIKE '%Watermelon%')
My database table data looks something like this :
id Vegetable fruits
----------------------
1 Spinach Apple
2 Cucumber Orange
3 Spinach Watermelon
The result of each id only can come out once.
<php>
$keywords = trim($_REQUEST['keyword']);
$keywords = preg_replace("/,\s*/", "|", $keyword);
$where = "[[:<:]](" . $keywords . ")[[:>:]]";
$sql = "SELECT * FROM table ";
$sql .= "WHERE vegetable REGEXP '" . $where . "' OR fruits REGEXP '" . $where . "'";
$result = mysqli_query($conn, $sql);
while ($rs = mysqli_fetch_array($result))
{
$vege = $rs["vegetable"];
$fruits = $rs["fruits"];
}
</php>
<html>
<form method=post>
<input type="text" class="form-control" placeholder="SEARCH..." value="<?=$keywords?>">
</form>
</html>
Here is the literal MySQL query using REGEXP:
SELECT *
FROM table
WHERE
(vegetable REGEXP '[[:<:]]Spinach[[:>:]]' OR fruits REGEXP '[[:<:]]Spinach[[:>:]]') AND
(vegetable REGEXP '[[:<:]]Watermelon[[:>:]]' OR fruits REGEXP '[[:<:]]Watermelon[[:>:]]');

How can i improve my search function ? PHP + MySQL

I'm new here and i started coding in PHP and using MySQL.
I want to search multiple "keywords", for example "Intel i7 7700k" in table and I have no idea how to accomplish this.
My structure of my MySQL Table looks like this:
id | brand | family | model | cores | threads etc.
1 | Intel | i7 | 7700k | 4 | 8 etc.
The following PHP search works, but only for one word.
if(isset($_GET['search'])){
$search = $conn->escape_string($_GET['search']);
$query = $conn->query("
SELECT brand, family, model
FROM cpus
WHERE brand LIKE '%{$search}%'
OR family LIKE '%{$search}%'
OR model LIKE '%{$search}%'
");
I was trying to loop the array of words, but it doesn't work.
if(isset($_GET['search'])){
$search = $conn->escape_string($_GET['search']);
$words = explode(' ',$search);
$searchout = foreach ($words as $word){
"SELECT brand, family, model FROM cpus WHERE brand LIKE '%$word%' OR family LIKE '%$word%' OR model LIKE '%$word%'"
}
$query = $conn->query($search_out);
echo "<div class='result-count'>Found " . $query->num_rows . " results.</div>";
if($query->num_rows){
while($r = $query->fetch_object()){
echo "<div class='result'><a href='#'>" . $r->brand . $r->model . "</a></div>";
}
}
}
How can i make the search working on multiple words?
Like "Intel i7 7700k" "7700k intel i7" "i7 7700k intel" etc.
Here is my another try which also failed:
if(isset($_GET['search'])){
$search = $conn->escape_string($_GET['search']);
$words = explode(' ',$search);
$words_count = count($words);
$cpus_columns = ['brand','family','model'];
print_r($cpus_columns);
$mysql_where = "SELECT brand, family, model FROM cpus WHERE ".$cpus_columns[0]." LIKE ".$words[0];
$mysql_loop = for ($i = 1; $i <= $words_count; $i++){
" OR ".$cpus_columns[$i]." LIKE ".$words[$i]
}
$mysql_query = $mysql_where . $mysql_loop;
$query = $conn->query($mysql_query);
echo "<div class='result-count'>Found " . $query->num_rows . " results.</div>";
if($query->num_rows){
while($r = $query->fetch_object()){
echo "<div class='result'><a href='#'>" . $r->brand . $r->model . "</a></div>";
}
}
}
I start slowly hating PHP and MySQL, 4 days and can't get it working this is just sad.
this is how i make a searching for somethg
in my case only for name ,but u can add more
$arry = array();
$arry = explode(" ",$POST["search"]);
$query="SELECT * FROM tblfbaccban WHERE ";
for($c=0;$c<sizeof($arry);$c++)
{
$query=$query."Name LIKE'%$arry[$c]%'";
if($c<sizeof($arry)-1)
{
$query=$query." OR ";
}
}
$sql=mysqli_query($mysqli,$query)or die(mysql_error());
while ($row = mysqli_fetch_array($sql, MYSQLI_BOTH))
{
echo $row["Name"]."<br>";
}

How can I scan all my fields in MySQL for form input

In my script below, the user inputs a form and rows are returned from a MYSQL table if rows are similar to inputted by the user. I am building a search engine and everything is based on rank. But I want to be able to adjust the code below to see how many times the word 'iPad' for example comes up with the row fields, which are 'title', 'description', 'keywords' and 'link'. If so, I want that row to return higher than say a row that has a higher id, but only mentions iPad once in all of the fields combined.
My code is below:
Terms together query:
$query = " SELECT * FROM scan WHERE ";
$terms = array_map('mysql_real_escape_string', $terms);
$i = 0;
foreach ($terms as $each) {
if ($i++ !== 0){
$query .= " AND ";
}
$query .= "title LIKE '%{$each}%' OR link LIKE '%{$each}%' OR keywords LIKE '%{$each}%' OR description LIKE '%{$each}%' ";
}
$query = mysql_query($query) or die('MySQL Query Error: ' . mysql_error( $connect ));
echo '<p class="time">Qlick showed your results in ' . number_format($secs,2) . ' seconds.</p>';
$numrows = mysql_num_rows($query);
if ($numrows > 0) {
while ($row = mysql_fetch_assoc($query)) {
$id = $row['id'];
$title = $row['title'];
$description = $row['description'];
$keywords = $row['keywords'];
$link = $row['link'];
$rank = $row['rank'];
Seperate Terms Query
$query = " SELECT * FROM scan WHERE ";
$terms = array_map('mysql_real_escape_string', $terms);
$i = 0;
foreach ($terms as $each) {
if ($i++ !== 0){
$query .= " OR ";
}
$query .= "title LIKE '%{$each}%' OR link LIKE '%{$each}%' OR keywords LIKE '%{$each}%' OR description LIKE '%{$each}%' ";
}
// Don't append the ORDER BY until after the loop
$query = mysql_query($query) or die('MySQL Query Error: ' . mysql_error( $connect ));
$numrows = mysql_num_rows($query);
if ($numrows > 0) {
while ($row = mysql_fetch_assoc($query)) {
$id = $row['id'];
$title = $row['title'];
$description = $row['description'];
$keywords = $row['keywords'];
$link = $row['link'];
$rank = $row['rank'];
I'd try to do this using an auxiliary field on which to run a FULLTEXT query, in which you would save all textual data:
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
The alternative is to run the filtering in MySQL and the ranking in PHP. You might squeeze some performance by running a single LIKE on the concatenated field.
By the way, your code above lacks parentheses in the LIKE, so that the results won't be correct: you mustn't ask WHERE field1 LIKE 'x' OR field2 LIKE 'x' AND field1 LIKE 'y' OR..., you must state WHERE (field1 LIKE 'x' OR field2 LIKE 'x') AND (field1 LIKE 'y' OR...).
// Here we search for ALL terms (all must be present at least once)
// use ' OR ' to ask that at least one term must be present once.
$where = array();
foreach($terms as $term)
$where[] = "( CONCAT(title,'|',link,'|',keywords) LIKE '%{$term}%')";
$query .= ' WHERE ' . '('.implode(' AND ', $where).')';
Now in the OR case you could do a simple ranking on the number of matched terms (with AND the number is always the total number of terms):
$select_fields[] '(' . implode ('+', $where) . ') AS ranking';
Otherwise in SQL you would need recourse to a really ugly hack:
(LENGTH(
REPLACE(CONCAT(title,'|',link,'|',keywords),'{$term}','')
) - LENGTH(CONCAT(title,'|',link,'|',keywords)))/LENGTH('{$term}');
This above calculates the difference between the total length of the text where the search is to be done and the total length of the same text, with search string removed. The difference is of course proportional to how many times the search string is there: if the string is 8 characters long, a difference of 32 would mean that it is present four times. Dividing the length difference by the length of the term, we obtain the number of hits.
The problem is that for several terms you have to complicate the query enormously, and it might be really expensive to run:
$select_fields = array('*');
$where = array();
$rank = array();
foreach($terms as $term)
{
// assume $term is NOT QUOTED
$search = mysql_real_escape_string($term);
$concat = "CONCAT(title,'|',link,'|',keywords)";
$where[] = "(${concat} LIKE '%{$search}%')";
$rank[] = "(LENGTH(REPLACE(${concat},'{$search}',''))
- LENGTH(${concat}))/LENGTH('{$search}')";
}
$select_fields[] = "(".implode(",", $rank).") AS ranking";
$query .= "SELECT " . implode(',', $select_fields)
. ' FROM scan WHERE (' . implode(' AND ', $where) . ')';

array_unique question

I have a search engine type website. It takes the users input, stores the query as $q, explodes the query and searches the database. It then displays the results with the name and web address of each result.
For example, if i searched for "computer programming"... Stack Overflow, stackoverflow.com would be my result. However, it displays twice. (once for computer, and once for programming.)
I tried to solve this with the array_unique function, and it does not work.
any help would be appreciated.
// trim whitespace
$trimmed = trim($q);
// seperate key-phrases
$trimmed_array = explode(" ", $trimmed);
// remove duplicates
$clean_array = array_unique($trimmed_array);
//query dataabase
foreach ($clean_array as $trimm){
$query = mysql_query("SELECT * FROM forumlist WHERE `keys` LIKE '%" . mysql_real_escape_string($trimm) . "%' ORDER BY rating DESC, total_ratings DESC") or die(mysql_error());
Thank you!
//query dataabase
$query = 'SELECT * FROM forumlist ';
$where = array();
foreach ($clean_array as $trimm){
$where[] = " `keys` LIKE '%" . mysql_real_escape_string($trimm) . "%' ";
}
if(!empty($where)){
$query .= " WHERE ". implode(' OR ', $where);
}
$query .= " ORDER BY rating DESC, total_ratings DESC";
$result = mysql_query($query) or die(mysql_error());

Categories