如何从字符串中删除单词?

How can I remove a word from a string?

我正在进行一个小实验,通过检查我指定的 SQL 关键字数组,将字符串 JERRY 附加到 sql 语句中的每个 sql 关键字。我想从搜索变量中删除字符串 JERRY,这样如果我键入一个' UNION (SELECT 1, fname, username, password FROM users);-- 在搜索输入字段中,打印的 sql 语句应如下所示;

SELECTJERRY * FROMJERRY shopping WHEREJERRY title LIKEJERRY '%a' UNION (SELECT 1, fname, username, password FROM users);-- %'

目标是我不希望输入搜索变量中的 SQL 关键字具有字符串 JERRY。

但是现在,这就是我得到的;

SELECTJERRY * FROMJERRY shopping WHEREJERRY title LIKEJERRY '%a' UNIONJERRY (SELECT 1, fname, username, password FROMJERRY users);-- %'

我怎样才能做到这一点?

$search = $_GET['search'];
if (empty($search)) {
    echo "Please fill in the search bar";

    exit();
}

$keywords = ["SELECT", "FROM", "WHERE", "LIKE", "AND", "OR", "ON","UNION", "JOIN"];
$sql = "SELECT * FROM shopping WHERE title LIKE '%$search%'";
$splittedSql = explode(" ", $sql);

foreach ($splittedSql as $sl) {

    if (in_array($sl, $keywords)) {

        $newstatement = $sl . "JERRY" . ' ';
    } else {
        $newstatement = $sl . ' ';
    }
    echo $newstatement;
}

由于 $search 会受到 explode 的影响,使用空格,我们可以通过用唯一字符替换空格来防止这种情况:

  $search = str_replace(" ","uniquecharacters",$search);

然后用白色替换那些独特的字符 space/s

$keywords = ["SELECT", "FROM", "WHERE", "LIKE", "AND", "OR", "ON","UNION", "JOIN"];
$search = str_replace(" ","uniquecharacters",$search);
$sql = "SELECT * FROM shopping WHERE title LIKE '%$search%'";
$splittedSql = explode(" ", $sql);

foreach ($splittedSql as $sl) {

    if (in_array($sl, $keywords)) {  
       $newstatement = $sl . "JERRY" . ' ';
    } else {
       $newstatement = str_replace("uniquecharacters"," ",$sl);
       $newstatement = $sl . ' ';
    }
    echo $newstatement;
 }

问题是您正在检查您的静态查询是否包含用户提供的 $search 值。实现您想要的结果需要对关键字替换进行限制。

一种方法是首先检查用户为指定关键字提供的 $search 值,如果存在,则更改您的静态查询。然后您可以在事后应用用户提供的 $search 值,这可以使用 sprintf.

轻松完成

您可以使用 preg_replace 使用捕获组 () 和替换值 JERRY 一次应用所有关键字值,而不是分解查询。 您可以在模式上使用单词边界 \b 以避免对 sANDtONlORe 等单词的误报

最后使用 stripos 检查 $search 值而不是 in_array()/i 正则表达式修饰符,将允许 $keyword 匹配和替换不区分大小写。

方法一:https://3v4l.org/ie2Mj

$search = 'a\' UNION (SELECT 1, fname, username, password FROM users);--';

$keywords = ["SELECT", "FROM", "WHERE", "LIKE", "AND", "OR", "ON","UNION", "JOIN"];

//sprintf requires textual percent signs to be escaped as %%
$query = 'SELECT * FROM shopping WHERE title LIKE \'%%%s%%\'';
foreach ($keywords as $w) {
    if (false !== stripos($search, $w)) {
        //found a keyword build the replacement capture groups.
        $patterns = '/\b(' . implode('|', $keywords) . ')\b/i';
        $query = preg_replace($patterns, 'JERRY', $query);
        break;
    }
}
printf($query, $search);

迭代 $keywords 的替代方法是使用 preg_match 确定 $search 值是否包含关键字值。

方法二:https://3v4l.org/iVbBc

$search = 'a\' UNION (SELECT 1, fname, username, password FROM users);--';
$keywords = ["SELECT", "FROM", "WHERE", "LIKE", "AND", "OR", "ON","UNION", "JOIN"];
$patterns = '/\b(' . implode('|', $keywords) . ')\b/i';
$query = 'SELECT * FROM shopping WHERE title LIKE \'%%%s%%\'';

if (preg_match($patterns, $search)) {
    $query = preg_replace($patterns, 'JERRY', $query);
}
printf($query, $search);

两种方法的结果:

SELECTJERRY * FROMJERRY shopping WHEREJERRY title LIKEJERRY '%a' UNION (SELECT 1, fname, username, password FROM users);--%'