Ok so when a user types their search phrase in the search input, I would like it to match the exact phrase or the key words entered.
I.e
So the title of a post is "Search the Database"
$searchVal = "Search database";
WHERE post_title LIKE '%" . $searchVal . "%'
The above code doesn't find a match as the title has "the" between Search Database.
How could I get it to match.
I thought maybe using explode but Im getting an error:
$sVals = explode(" ", $searchVal);
foreach ($sVals as $s) {
$querySearchVals .= "OR post_title LIKE '%" . $s . "%'";
}
Hope that makes sense.
Cheers
Maybe this could help
$search_key = $_POST['searchkey']; //take the search text from the post method
$search_words = array();
$search_words = explode(" ",$search_key);
$q_string = "";
$last_index = intval(count($search_Words)) - 1;
for($i = 0; $i<count($search_Words);$i++)
{
$q_string = $q_string . " post_title LIKE '%$search_words[$i]%' ";
if($i != $last_index)
$q_string = $q_string . " OR ";
}
And to make it even more accurate, you may skip the articles like A, The, An etc
You may want to insert the % in between the words and execute with 1 where clause. some thing like below should work.
$searchVal = "Search database";
$querySearchVals = "post_title LIKE '%";
$sVals = explode(" ", $searchVal);
foreach ($sVals as $s) {
$querySearchVals .= $s."%";
}
$querySearchVals .= "'";
echo $querySearchVals;
Hope it helps!
Related
I am trying to build the logic to create a multi word LIKE statement for use with PDO.
This takes the search string $str to build the multiple parts of the LIKE section:
$str = $_POST['str'];
$keywords = preg_split('/[\s]+/', $str);
$totalKeywords = count($keywords);
$search = "%$str%";
$sql_str = " AND post_content LIKE :search0 ";
for($i=1 ; $i < $totalKeywords; $i++){
$search_bit = ":search" . $i;
$sql_str .= " AND post_content LIKE $search_bit ";
}
This is the SQL statement - with the $sql_str slotted into the correct point:
$sql = "SELECT d.ID
, d.post_date
, d.post_content
, d.post_cat_id
, d.post_label
, c.fld_cat
FROM tbl_log_days d
, tbl_log_cats c
WHERE d.post_cat_id = c.fld_id " . $sql_str . "
ORDER BY post_date";
Then for binding the variables, I have tried two approaches:
$stmt = $pdo->prepare($sql);
if (!empty($sql_str)) {
foreach ($keywords as $key => &$keyword){
$foo = '%'.$keyword.'%';
$stmt->bindParam(':search' . $key, $foo);
}
}
And also this (without the ampersand before the $keyword in the foreach line):
$stmt = $pdo->prepare($sql);
if (!empty($sql_str)) {
foreach ($keywords as $key => $keyword){
$foo = '%'.$keyword.'%';
$stmt->bindParam(':search' . $key, $foo);
}
}
However, when I search for e.g. "past hill" and check the resulting SQL that is actually run (I enabled query logging in MySQL), it only takes the last word in the search string:
SELECT d.ID
, d.post_date
, d.post_content
, d.post_cat_id
, d.post_label
, c.fld_cat
FROM tbl_log_days d
, tbl_log_cats c
WHERE d.post_cat_id = c.fld_id AND post_content LIKE '%past%' AND post_content LIKE '%past%'
ORDER BY post_date
I have done a var_dump of the $keyword variable when running a search and it returns:
string(4) "hill"
string(4) "past"
I can't work this one out. Is it possible to do what I'm trying to do?
I would do something like this
for($i=1 ; $i < $totalKeywords; $i++){
$search_num = "search" . $i;
$search_bit = ":" . $search_num;
$sql_str .= " AND post_content LIKE $search_bit ";
$foo = '%'.$keyword.'%';
$V[$search_bit] = $foo;
}
$query = $pdo->prepare($sql);
$query->execute($V);
(I haven't tested this code, so please excuse typos.)
I asked the same question on Sitepoint:
https://www.sitepoint.com/community/t/multi-word-like-prepared-statement-for-pdo-query/223738/5
And got a solution there:
$stmt = $pdo->prepare($sql);
if (!empty($sql_str)) {
for ($x = 0; $x<$totalKeywords; $x++) {
// add the percent signs, or make a new copy of the array first if you want to keep the parameters
$keywords[$x] = "%" . $keywords[$x] . "%";
$stmt->bindParam(':search' . $x, $keywords[$x]);
}
}
I am trying to craft a multiword search that will query multiple columns in a table. My code works great thus far for a single column, but as you can imagine using it for more then one column becomes an issue.
If I add orWhere it won't work, and I don't really want to create more for loops because it will become quite cumbersome. Any Ideas?
$query = $request->getParameter("article-search");
$keywords = explode(" ", $query);
for( $i = 1; $i <= count( $keywords ); $i++ ){
$q->addWhere("a.title LIKE ?", "%" . $keywords[$i - 1] . "%");
}
I just did it like this.. Maybe it helps somebody..
$now = "some other parameter";
$parts = explode(" ",trim($searchtext));
$clauses=array();
// static paramtter setted here
$parameters = array(
':now' => $now
);
$i = 0;
foreach ($parts as $part){
// for every word make new search query and parameter
$parameters[":param".$i] = "%".$part."%";
if($i == 0){
$clauses = "v.description LIKE :param".$i." OR v.name LIKE :param".$i." OR v.sale LIKE :param".$i;
} else {
$clauses .= " OR v.description LIKE :param".$i." OR v.name LIKE :param".$i." OR v.sale LIKE :param".$i;
}
$i ++;
}
$qb->select('v')
->from('MyBundle\Entity\Voucher', 'v')
->where('v.date_start <= :now')
->andWhere('v.date_end >= :now')
->andWhere($clauses)
->setParameters($parameters);
Usually I would write this as a query that looks something like the following:
$query = "`where column like '%$keywordOne%' or column like '%keywordTwo%'`";
Though I'm not sure how you implement that with the query-building tool you have there.
Here's a quick example that might help build the where portion of the query using the array of keywords you have:
<?php
$keywords = array("bing", "bang", "jump");
$query_start = 'where colummName';
$like_portion = "like '%" . implode("%' or columnName like '%", $keywords) . "%'";
if(sizeof($keywords) > 0) {
echo "`$query_start $like_portion`";
} else {
// No keywords
}
?>
Let me know if there's anything I can clarify here
Maybe you can consider using "union"? Also, for such complex queries, I would use native SQL instead of ORM practice.
I am trying to implement a multiple and keyword search in my application, but it searches only for the last word in the input and ignores the rest of the input can someone please help me with issue, below is my code...
$where_clause=array();
if(!empty($vResume_screen))
{
// trim whitespace from the stored variable
$trimmed = trim($vResume_screen);
// separate key-phrases into keywords
$trimmed_array = explode(" ",$trimmed);
// count keywords
$trimm_total = count($trimmed_array);
$i = 0;
$searchstring = '';
// looping to get the search string
foreach ($trimmed_array as $trimm)
{
if ($i != 0 and $i != $wordcount)
{
$searchstring .= " AND ";
}
$searchstring .= "resume_text LIKE '%$trimm%'";
// incrementing the value
$i = $i + 1;
}
$where_clause[]="resume_text like '%".$searchstring."%'";
}
I just changed your code a little bit, take a look...
$where_clause=array();
if(!empty($vResume_screen))
{
// separate key-phrases into keywords
$trimmed_array = explode(" ", trim($trimmed));
// count keywords
$trimm_total = count($trimmed_array);
$searchstring = '';
// looping to get the search string
foreach ($trimmed_array as $trimm)
{
if (!empty($searchstring)) {
$searchstring .= " OR "; //If you want to put the same condition for different keywords, you need to use OR.
}
$searchstring .= " resume_text LIKE '%" . $trimm . "%' ";
}
array_push($where_clause, $searchstring);
}
I dont know why you need the $where_clause to be an array but i did not change...
I have a search get variable that can contain multiple words which are space deliminated. I have used the following to script to grab the url variable. Notice for the example I have just used a string for simplicity.
What I have tried to do is explode the variable value and then add on the needed sql before and after.
The echo works fine. It is this echo that I need as a variable in a sql within the code that follows.
My problem is that it just returns the last query metal when I reference it outside within the query as a string. I am so new to this, please any help would appreciated.
<?php
$string = "kitchens wooden metal";
$splitted = explode(" ",$string);
$cnt = count($splitted);
$i=0;
while($cnt > $i)
{
$sqlsnippet = "cats_sub.cats_sub_ms_desc LIKE %$splitted[$i]%";
$i++;
echo $sqlsnippet;
}
?>
$sqlsnippet = "cats_sub.cats_sub_ms_desc LIKE %$splitted[$i]%";
This overrides $sqlsnippet for every iteration of the while-loop. That's the reason why you only get the last SQL snippet.
You need to concatenate the SQL snippets, like this:
$sqlsnippet = 'WHERE ';
foreach($i = 0; $i < count($splitted); $i++)
{
// Append AND
if($i > 0)
{
$sqlsnippet .= ' AND ';
}
$sqlsnippet .= 'cats_sub.cats_sub_ms_desc LIKE %' . mysql_real_escape($splitted[$i]) . '%';
}
var_dump($sqlsnippet);
My code:
<?php
$string = "kitchens wooden metal";
$splitted = explode(" ",$string);
$cnt = count($splitted);
$i=0;
while($cnt > $i)
{
$sqlsnippets[] = "cats_sub.cats_sub_ms_desc LIKE '%$splitted[$i]%'";
$i++;
}
$sqlsnippet = "(" . implode(" or ", $sqlsnippets) . ")";
echo $sqlsnippet;
?>
Result:
(cats_sub.cats_sub_ms_desc LIKE '%kitchens%' or cats_sub.cats_sub_ms_desc LIKE '%wooden%' or cats_sub.cats_sub_ms_desc LIKE '%metal%')
Optimized version:
<?php
$string = "kitchens wooden metal";
$sqlsnippet = "(cats_sub.cats_sub_ms_desc LIKE '%" . preg_replace("/ /", "%' or cats_sub.cats_sub_ms_desc LIKE '%", $string) . "%')";
echo $sqlsnippet;
?>
Let's say i have:
$title = "Rihanna - Man Down";
and a database multiple rows including one with a field called "name" with the "Rihanna" value
now... how can i check if in $title exists "Rihanna" and if it does how to add a link on "Rihanna" like this:
with other words check if one of the expresions from $title exists the database
i think this second formulation it is better
Rihanna - Man Down
I want to do something like youtube does at some of it;s music videos to be more clear
If I understood correct, this can do the work:
Then first search in DataBase, your query must be something like this:
//Search for word in DataBase on filed "name"
$title = "Rihanna - Man Down";
$arr = explode('-', $title);
$title = $arr[0];
$result = mysql_query("SELECT name FROM table WHERE name LIKE '%" . mysql_real_escape_string($title) . "%'");
//If find results, then we replace and generate links in this loop
while($row = mysql_fetch_array( $result )) {
$str = str_replace($title, ''.$title.'', $row['name']);
echo $str; //Rihanna - Man Down
}
$words = explode("-", $title);
$result = array();
foreach ($words as $word)
{
$word = trim($word);
$res = mysql_query("SELECT name FROM table WHERE name='" . mysql_real_escape_string($word) . "'");
if (mysql_num_rows($res) > 0)
{
$result[] = '' . $word . '';
}
else
{
$result[] = $word;
}
}
$result = implode($result, " - ");
This will however also link to "artist?id=Pink" if a song from another artist is named Pink, but you have the artist Pink in your database.
Split your title into words, and for each word check if your database contains row with that name. If yes, replace occurences of the word with link.
foreach (preg_split("/\s+/", $title) as $word) {
if (word_in_database($word)) {
$title = str_replace($word, "$word", $title);
}
}