Escape string for use in MySQL fulltext search

回眸只為那壹抹淺笑 提交于 2020-01-22 07:11:13

问题


I am using Laravel 4 and have set up the following query:

if(Input::get('keyword')) {
    $keyword = Input::get('keyword');
    $search = DB::connection()->getPdo()->quote($keyword);
    $query->whereRaw("MATCH(resources.name, resources.description, resources.website, resources.additional_info) AGAINST(? IN BOOLEAN MODE)", 
        array($search)
    );
}

This query runs fine under normal use, however, if the user enters a string such as ++, an error is thrown. Looking at the MySQl docs, there are some keywords, such as + and - which have specific purposes. Is there a function which will escape these types of special characters from a string so it can be used in a fulltext search like above without throwing any errors?

Here is an example of an error which is thrown:

{"error":{"type":"Illuminate\\Database\\QueryException","message":"SQLSTATE[42000]: Syntax error or access violation: 1064 syntax error, unexpected '+' (SQL: select * from `resources` where `duplicate` = 0 and MATCH(resources.name, resources.description, resources.website, resources.additional_info) AGAINST('c++' IN BOOLEAN MODE))","file":"\/var\/www\/html\/[...]\/vendor\/laravel\/framework\/src\/Illuminate\/Database\/Connection.php","line":555}}

Solutions I've tried:

$search = str_ireplace(['+', '-'], ' ', $keyword);

$search = filter_var($keyword, FILTER_SANITIZE_STRING);

$search = DB::connection()->getPdo()->quote($keyword);

I'm assuming I will need to use regex. What's the best approach here?


回答1:


Only the words and operators have meaning in Boolean search mode. Operators are: +, -, > <, ( ), ~, *, ", @distance. After some research I found what word characters are: Upper case, Lower case letters, Numeral (digit) and _. I think you can use one of two approaches:

  1. Replace all non word characters with spaces (I prefer this approach). This can be accomplished with regex:

    $search = preg_replace('/[^\p{L}\p{N}_]+/u', ' ', $keyword);
    
  2. Replace characters-operators with spaces:

    $search = preg_replace('/[+\-><\(\)~*\"@]+/', ' ', $keyword);
    

Only words are indexed by full text search engine and can be searched. Non word characters isn't indexed, so it does not make sense to leave them in the search string.

References:

  • Boolean Full-Text Searches
  • Fine-Tuning MySQL Full-Text Search (see: "Character Set Modifications")
  • PHP: preg_replace
  • PHP: Unicode character properties
  • PHP: Possible modifiers in regex patterns


来源:https://stackoverflow.com/questions/26507087/escape-string-for-use-in-mysql-fulltext-search

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!