我正在尝试匹配用户输入的所有单词
。
我正在使用php
v7
和mysql v 5.7.9
mysql innodb fulltext
搜索 bool 模式
.
但是当我在搜索中使用 @
等特殊字符时,我的搜索不断中断。
我尝试了很多组合,我怎样才能实现这样的目标?
现在我就是这样做的。
用于获取记录数
$get_count_query = "SELECT count(*) as total_count FROM content WHERE MATCH(title) AGAINST('". mysqli_real_escape_string ($conn, $_GET['q'])."' IN BOOLEAN MODE) AND is_enabled = 1 " ;
但是如果我搜索
Adobe Premier pro -
我的查询变成
SELECT count(*) as total_count FROM content WHERE MATCH(title) AGAINST('Adobe Premier pro -' IN BOOLEAN MODE) AND is_enabled = 1
我明白了
syntax error, unexpected $end
当末尾有特殊字符时,也会发生同样的情况。
我可以匹配所有单词。,通过在每个单词前添加 +
。,
但是假设有人尝试搜索
Adobe Premier pro - tda
我的查询变成了
SELECT count(*) as total_count FROM content WHERE MATCH(title) AGAINST('+Adobe +Premier +pro - +tda' IN BOOLEAN MODE) AND is_enabled = 1
我明白
syntax error, unexpected '+'
解决这个问题的方法是什么?
我只想允许 +
、-
、*
特殊字符作为搜索运算符。
更新1:
所以我尝试使用准备好的语句。,
$query = "SELECT count(*) as total_count FROM content WHERE MATCH(title) AGAINST(? IN BOOLEAN MODE) AND is_enabled = 1" ;
if ($stmt = mysqli_prepare($conn, $query)) {
/* bind parameters for markers */
mysqli_stmt_bind_param($stmt, 's', $_GET['q']);
/* execute statement */
mysqli_stmt_execute($stmt);
/* bind result variables */
mysqli_stmt_bind_result($stmt, $rrow['total_count']);
/* store result */
mysqli_stmt_store_result($stmt);
/* fetch values */
while (mysqli_stmt_fetch($stmt)) {
printr($rrow);
}
/* free result */
mysqli_stmt_free_result($stmt);
/* close statement */
mysqli_stmt_close($stmt);
}
/* close connection */
mysqli_close($conn);
并搜索
Adobe Premier pro -
并且输出为空白。
我在这里缺少什么?
<小时/>更新2:
我试图复制 TPB 搜索的工作原理。到目前为止,我已经做到了,并且工作完美。 我只允许 - , * mysql 参数。, 代码很丑陋,但它确实按预期工作
//sanitize user input before sending it to db
function sanitize_keyword($keyword){
$keyword_array = explode(' ', $keyword) ;
$keyword_array = array_values(array_filter($keyword_array)) ;
foreach($keyword_array as $key => $word){
//pass it to db
/* if (($key = array_search('(', $keyword_array)) !== false) {
unset($keyword_array[$key]);
} */
//pass it to db
/* if (($key = array_search(')', $keyword_array)) !== false) {
unset($keyword_array[$key]);
} */
//dont pass it to db
if (($key = array_search('*', $keyword_array)) !== false) {
unset($keyword_array[$key]);
}
//dont pass it to db
if (($key = array_search('+', $keyword_array)) !== false) {
unset($keyword_array[$key]);
}
//pass it to db
/* if (($key = array_search('-', $keyword_array)) !== false) {
unset($keyword_array[$key]);
} */
//dont pass it to db
if (($key = array_search('<', $keyword_array)) !== false) {
unset($keyword_array[$key]);
}
//dont pass it to db
if (($key = array_search('>', $keyword_array)) !== false) {
unset($keyword_array[$key]);
}
//dont pass it to db
if (($key = array_search('@', $keyword_array)) !== false) {
unset($keyword_array[$key]);
}
//pass it to db
/* if (($key = array_search('~', $keyword_array)) !== false) {
unset($keyword_array[$key]);
} */
}
$keyword_array = array_values(array_filter($keyword_array)) ;
//printr($keyword_array) ;
$out_array = array();
//loop through array, using increment, so we can jump to next value
for($i=0 ; $i <= count($keyword_array); $i++){
if(isset($keyword_array[$i])){
//if there is space in - and word then, we get next value
if($keyword_array[$i] == '-'){
//get next word
if(isset($keyword_array[$i+1]) && strlen($keyword_array[$i+1]) > 0){
$out_array[] = '-'.$keyword_array[$i+1];
$i = $i + 1;
}
}elseif(isset($keyword_array[$i]) && strlen($keyword_array[$i]) > 0 && $keyword_array[$i][0] == '-'){
//if word starts with -, then dont add + sign
//add word as it is
$out_array[] = $keyword_array[$i] ;
}elseif(strpos($keyword_array[$i], '-') !== false){
//if word contains - sign in the middle
//explode and create words of array
$all_words_array = explode('-', $keyword_array[$i]) ;
//remove empty values
$all_words_array = array_values(array_filter($all_words_array)) ;
//printr($all_words_array) ;
//add each word in final array
foreach($all_words_array as $word_t){
$out_array[] = '+'.$word_t;
}
}else{
//its just some regular word, add it in out array
$out_array[] = '+'.$keyword_array[$i];
}
}
}
//printr($out_array) ;
return implode(' ', $out_array) ;
}
最佳答案
您可以轻松地使用一些 Mysql 全文搜索不支持的特殊字符来清理搜索字符串。您可以使用此功能进行逃生和清理。
/**
* @param string $keyword
* @return string
*/
public function sanitizeKeyword($keyword)
{
$keywordArray = explode(' ', $keyword);
$specialChar = ['*', '+', '-', ' ', '(', ')', '~', '@','%', '<', '>'];
$finalKeywords = [];
//loop through array, using foreach, so we can prepare proper keywords array
foreach ($keywordArray as $keyword) {
if (in_array($keyword, $specialChar) || empty($keyword) || strlen($keyword) < 3) {
continue;
}
if (in_array(substr($keyword, 0, 1), ['+', '-','~','*', '@', '<', '>'])) {
$keyword = substr($keyword, 1);
}
//add each word in final array
$finalKeywords[] = $keyword;
}
// create final string with space and + sign
$finalString = implode(' +', $finalKeywords);
if (!empty($finalString)) {
$finalString = '+'.$finalString;
}
return $finalString;
}
关于PHP mysql全文 bool 搜索,如何清理搜索的关键字并匹配所有单词?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46960221/