// Check and set search
if($_POST['searchQuery'] !== "null"){
$search = $_POST['searchQuery'];
$search = explode(' ', $search);
//long words are more than 4
$longwords = '';
$shortwords = '';
$searchCount = count($search);
foreach ($search as $word) {
$word = trimplural($word);
if ($searchCount > 1){
if (strlen($word) > 3) {
if (!in_array($word,array('sale','brand','lots'))){
$longwords.=' +'.$word;
} //check for words
}else{ //else 3 letters
if (strlen($word) == 3) {
if (!in_array($word,array('and','the','him','her','for','new','you'))){
$shortwords.= " OR (fname LIKE '%$word%' OR lname LIKE '%$word%') ";
} //search for words
}//strlen == 3
}
}else{//else searchcount == 1
if (!in_array($word,array('and','the','him','her','for','new','you'))){
$shortwords.= " OR (fname LIKE '%$word%' OR lname LIKE '%$word%') ";
}
}
}
}else{
$search = null;
}
SQL:
$sql = "SELECT * FROM people WHERE MATCH (lname,fname) AGAINST (:longwords IN BOOLEAN MODE) $shortwords LIMIT " . $postnumbers . " OFFSET ".$offset;
$q1 = $conn->prepare($sql) or die("failed!");
$q1->bindParam(':uniid', $uniid, PDO::PARAM_STR);
$q1->bindParam(':longwords', $longwords, PDO::PARAM_STR);
$q1->execute();
我有一个使用上面显示的代码生成的搜索查询,我想结合使用 mysql 全文搜索和 LIKE 查询。为了做到这一点,我添加了部分SQL查询作为变量$shortwords
以使LIKE部分工作,但是,我知道由于SQL注入,这不是最佳选择。
在实现到 SQL 之前,如何使此查询"更安全"或清理输出?
创建子句时,在将变量添加到字符串之前,在$word变量上使用 PDO::quote,它将清理并转义该值。 然后,您不需要将 Param 与短词绑定,但您将获得相同的功能。
这样的事情应该有效:
if (!in_array($word,array('and','the','him','her','for','new','you'))){
$safe = $conn->quote('%'.$word.'%');
$shortwords.= " OR (fname LIKE $safe OR lname LIKE $safe) ";
} //search for words
虽然偏移量和后缀号并不容易受到注入,但绑定它们仍然可能很好,这将使查询更具可读性,但这只是我的意见。
此外,您可能需要考虑在 foreach 之外定义单词列表数组。 目前,解释器正在循环的每次迭代中重建数组。 同样,没什么大不了的,但值得一提。