1 回答
TA贡献1946条经验 获得超3个赞
您的代码对SQL 注入相关的攻击是开放的。甚至real_escape_string无法完全保护它。请学习改用Prepared Statements。
现在,除了上述建议之外,还有两个可能的进一步修复:
修复 #1您用于将输入字符串标记为 FTS 单词的 php 代码不足。前段时间,我确实创建了一个函数来以更强大的方式处理这个需求。您可以改用以下内容:
/**
* Method to take an input string and tokenize it into an array of words for Full Text Searching (FTS).
* This method is used when an input string can be made up of multiple words (let's say, separated by space characters),
* and we need to use different Boolean operators on each of the words. The tokenizing process is similar to extraction
* of words by FTS parser in MySQL. The operators used for matching in Boolean condition are removed from the input $phrase.
* These characters as of latest version of MySQL (8+) are: +-><()~*:""&|
* We can also execute the following query to get updated list: show variables like 'ft_boolean_syntax';
* Afterwards, the modified string is split into individual words considering either space, comma, and, period (.) characters.
* Details at: https://dev.mysql.com/doc/refman/8.0/en/fulltext-natural-language.html
* @param string $phrase Input statement/phrase consisting of words
* @return array Tokenized words
* @author Madhur, 2019
*/
function tokenizeStringIntoFTSWords(string $phrase) : array {
$phrase_mod = trim(preg_replace('/[><()~*:"&|+-]/', '', trim($phrase)));
return preg_split('/[\s,.]/', $phrase_mod, null, PREG_SPLIT_NO_EMPTY);
}
修复 #2似乎您正在尝试通过按以下顺序给予优先级来对搜索进行排名:
文本中的所有单词>第一个单词 AND 其余两个单词>中的任何一个 至少三个单词中的任何一个。
但是,如果您阅读全文搜索文档,您可以使用相关性进行排序MATCH(),因为它还返回相关性分数。
当MATCH()在WHERE子句中使用时,返回的行将自动以最高相关性优先排序(不幸的是,这仅适用于 NATURAL 模式,而不适用于 BOOLEAN 模式)。相关性值是非负浮点数。零相关性意味着没有相似性。相关性是根据行(文档)中的单词数、行中唯一单词的数量、集合中的单词总数以及包含特定单词的行数来计算的。
所以基本上,文本中的所有单词已经比这三个单词中的任何一个都具有更高的相关性。现在,如果你需要给第一个词更高的优先级,你只需要>在第一个词上使用操作符。因此,您只需要以下单个查询:
SELECT * FROM movie
WHERE
MATCH(name)
AGAINST('>:first_word :second_word :third_word ..and so on)' IN BOOLEAN MODE)
ORDER BY
MATCH(name)
AGAINST('>:first_word :second_word :third_word ..and so on)' IN BOOLEAN MODE)
DESC
LIMIT 20
- 1 回答
- 0 关注
- 153 浏览
添加回答
举报