Building MySQL searching query using LIKE in PHP - php

I make a PHP MySQL search, the custom may be type something like word or word1 word2 or word1 word2 word3... I need to get the final query like
$qry = "SELECT title,content,date
FROM articles WHERE
(title like '%$word1%' and title '%$word2%')
OR
(content like '%$word1%' and content title '%$word2%')"
OR
(title like '%$word1%' and content title '%$word2%')
OR
(title like '%$word2%' and content title '%$word1%'); // make sure custom type words all match in database column title and content, maybe only '%$word1%', or maybe multi words '%$word1%', '%$word2%', '%$word3%'...
I use some code below, but it could not reach my request. how to make it right? Thanks.
$qry = "SELECT title,content,date FROM articles";
if($_REQUEST['search']!=""){
$searchText = $_REQUEST['search'];
$words = preg_split("/\s+/",$searchText);
$uniqueWords = array_keys(array_flip($words));
$parts = '';
foreach($uniqueWords as $word){
$parts[] = " content like '%$word%' ";
}
$where = implode(" AND ", $parts);
foreach($uniqueWords as $word){
$parts[] = " title like '%$word%' ";
}
$where1 = implode(" AND ", $parts);
foreach($uniqueWords as $word){
$parts[] = " title like '%$word%' OR content like '%$word%' ";
}
$where2 = implode(" AND ", $parts);
$qry .=" WHERE $where OR $where1 OR $where2 Order By date DESC ";
}

I'm not sure exactly what you're after (are you wanting to match any keyword in title or contents or match both keywords to both columns...?) But what about something like this:
$keywords = explode(' ',mysql_real_escape_string($_REQUEST['search']));
$qry = "SELECT title,content,date FROM articles WHERE (";
$qry2 = '';
foreach($keywords as $n => $word)
{
$qry2 .= " title LIKE '%$word%' OR content LIKE '%$word%' OR";
}
$qry .= trim($qry2, 'OR');
$qry .= ") ORDER BY title";
Not tested this, but it seems ok.

Related

Search for different tables with multiple words

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.

how to perform a multi sql search via php in one field

i am using this sql search to find a title and artist in my database. I have on field containing infos like "ref.1570 title artist.mp4". When I do the search it works but in one direction only, i would like to get the result whatever the order i do the search... to be more precise if i search "title artist" no problem i found it. If i search "artist title" no way ... how can you help me making php sql search both directions ?
Best regards and thank you for your help.
Phil
i am using this code :
if ($search != null) {
$sql = 'SELECT * FROM `catalog` WHERE (`file`LIKE "%' . $search . '%")';
$sqlCount = 'SELECT count(*) FROM `catalog` WHERE (`file`LIKE "%' . $search . '%")';
}
Why don't you split keyword $search with space and append with Like statement in the query. Eg:
if ($search != null) {
$keywords=explode(" ",$search);
$sql = 'SELECT * FROM `catalog` WHERE 1=1'; // just to append OR condition.This won't affect anything as the condition will always be true.
$sqlCount = 'SELECT count(*) FROM `catalog` WHERE 1=1 ';
foreach($keywords as $key){
if(!empty($key)){
$sql.=' And file Like \'%'.$key.'\%';
$sqlCount.=' And file Like \'%'.$key.'\%';
}
}
}
I believe this will work as you expected.
I think you won't get around a foreach:
if ($search != null) {
$arrayOfSearchTerms = explode(' ', $search);
$sql = 'SELECT * FROM `catalog` WHERE ';
$sqlCount = 'SELECT count(*) FROM `catalog` WHERE ';
$termNumber = 0;
foreach ($arrayOfSearchTerms as $term) {
$addingSql = '';
if ($termNumber > 0) {
$addingSql = ' OR ';
}
$addingSql .= '(`file` LIKE "%') . $term . '%")';
$sql .= $addingSql;
$sqlCount = $addingSql;
$termNumber++;
}
}
You need to iterate over your search terms and add this terms into your 'LIKE'-Statement
you can try this research: it does a LIKE %word% for every word. If you want more powerfull research you should use tools like elasticsearch etc...
This way you could do:
$parts = explode(" ",$search)
$queryParts = array();
foreach ($parts as $part) {
$queryParts[] = `artist`LIKE "%' . $part . '%" ;
}
// this way we can have like %artist% AND like %title%
$querySearch= implode(" AND ", $queryParts);
$sql = 'SELECT * FROM `catalog` WHERE (". $querySearch .")';
$sqlCount = 'SELECT count(*) FROM `catalog` WHERE (`". $querySearch .")';
you have solved my problem i know now hos to correctly explode a request into variables ..
$search = $name;
$explode=explode(" ",$search);
print_r (explode(" ",$explode));
and then i use my sql request like this
$sql = 'SELECT * FROM `catalog` WHERE (`idc` LIKE "%' . $search . '%" OR `file` LIKE "%' . $search . '%" OR `title` LIKE "%' . $explode[0] . '%" AND `artist`LIKE "%' . $explode[1] . '% " OR `artist`LIKE "%' . $explode[0] . '%" AND `title`LIKE "%' . $explode[1] . '%")';
and it is working !
COOL
Use the multi query functions,
in mysqli should be : mysqli_multi_query();
More info on : Mysqli Multiquery

php mysql search from 2 columns

$where = "";
$keywords =preg_split('/[\s]+/', $keywords);
$total_keywords = count($keywords);
foreach($keywords as $key=>$keyword) {
$where .= "`title` LIKE '%$keyword%'";
if ($key != ($total_keywords - 1)) {
$where .= " AND ";
}
}
$results = "SELECT `id`, `username`, `title`, LEFT(`description`, 90) as `description`, `file`, `code`, `type`, `size`, `date` FROM `files` WHERE $where ORDER BY id DESC LIMIT $start, $per_page";
$where .= "`title` LIKE '%$keyword%'"; // this case I am searching only in column `title` I want to search too in column `type` with sign '.' I don't know how to include '.' in search result for `type`
Example search for file.exe and get all results with this condition file.exe. Or somebode search only .exe get all results with type .exe
$where .= "title, type LIKE '%$keyword%'";//I did it like this no result
$where .= "title AND type LIKE '%$keyword%'";//I did it like this no result
$where .= "title LIKE '%$keyword%' AND type LIKE '%$keyword%'";//I did it like this no result
Someone knows how I can get it my results with title type with sign '.'???
$where .= "`title` LIKE '%$keyword%' OR type LIKE '$type'";
Updated Code
$pos = strpos($keyword, '.');
if($pos > 0) {
$parts = explode('.', $keyword);
$type = array_pop($parts);
$file = array_pop($parts);
$where .= "`title` LIKE '%$file%' AND type LIKE '%$type%'";
}
else {
$where .= "`title` LIKE '%$keyword%' OR type LIKE '%$type%'";
}
$where .= "`title` LIKE '%$keyword%' OR type LIKE '%$type%'";

php code not working the way I want it for Search function

Searching one word works perfectly. I would like to have two or more words work as well.
So far I got this far, with the results being this if I search multiple words:
SELECT id, title, tag, type
FROM table WHERE **AND** p.id LIKE '%flower%' OR title LIKE '%flower%' OR tag LIKE '%flower%' OR type LIKE '%flower%'
AND p.id LIKE '%floral%' OR title LIKE '%floral%' OR tag LIKE '%floral%' OR type LIKE '%floral%'
ORDER BY title
How do I make use of the AND properly so that when there is more than one word search I don't get the extra AND in my code.
Is there a more efficient way?
if (count($error) < 1) {
$searchSQL = "SELECT id, title, tag, type
FROM table
WHERE ";
$searcheach = explode(" ", $searchTerms);
foreach($searcheach as $searchword) {
//if more than one word do this else do that
if(strpos(trim($searchTerms), ' ') !== false) {
$searchSQL .= "AND p.id LIKE '%{$searchword}%'
OR title LIKE '%{$searchword}%'
OR tag LIKE '%{$searchword}%'
OR type LIKE '%{$searchword}%' ";
}
else {
$searchSQL .= "p.id LIKE '%{$searchword}%'
OR title LIKE '%{$searchword}%'
OR tag LIKE '%{$searchword}%'
OR type LIKE '%{$searchword}%' ";
}
}
$searchSQL .= "ORDER BY title";
$words = explode(' ', $searchTerms);
$clauses = array()
foreach($words as $word) {
$safeword = mysql_real_escape_string($word);
$clauses[] = "(p.id LIKE '%{$safeword}%' OR title LIKE '%{$safeword} OR etc... )";
}
$clause = implode(' AND ', $clauses);
$sql = "SELECT ... WHERE $clause ORDER BY title";
I would rather do
$searchSQL = "SELECT id, title, tag, type
FROM table
WHERE (1=1)";
Now you can always prepend AND before each condition
Also, it looks like you missed parenthesis, I believe it should be
$searchSQL .= "AND (p.id LIKE '%{$searchword}%'
OR title LIKE '%{$searchword}%'
OR tag LIKE '%{$searchword}%'
OR type LIKE '%{$searchword}%') "
I usually use the 1=1 filter so that when searching for multiple words, the sql will be:
SELECT id, title, tag, type
FROM table
WHERE 1=1
AND p.id LIKE '%flower%'
OR title LIKE '%flower%'
OR tag LIKE '%flower%'
OR type LIKE '%flower%'
AND p.id LIKE '%floral%'
OR title LIKE '%floral%'
OR tag LIKE '%floral%'
OR type LIKE '%floral%'
ORDER BY title
And the code to do that would be:
if (count($error) < 1) {
$searchSQL = "SELECT id, title, tag, type
FROM table
WHERE 1=1";
$searcheach = explode(" ", $searchTerms);
foreach($searcheach as $searchword) {
//if more than one word do this else do that
if(strpos(trim($searchTerms), ' ') !== false) {
$searchSQL .= " AND p.id LIKE '%{$searchword}%'
OR title LIKE '%{$searchword}%'
OR tag LIKE '%{$searchword}%'
OR type LIKE '%{$searchword}%' ";
}
else {
$searchSQL .= "p.id LIKE '%{$searchword}%'
OR title LIKE '%{$searchword}%'
OR tag LIKE '%{$searchword}%'
OR type LIKE '%{$searchword}%' ";
}
}
$searchSQL .= "ORDER BY title";
I tend to build up all my terms as an array and then use implode:
foreach($searcheach as $searchword) {
$sqlSearchTerms[] = "p.id LIKE '%{$searchword}%'
OR title LIKE '%{$searchword}%'
OR tag LIKE '%{$searchword}%'
OR type LIKE '%{$searchword}%' ";
}
$searchSQL .= implode(' AND ', $sqlSearchTerms);

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