1

我将创建数据库表badwords来存储一些不需要的单词 [ id,word],如下所示。

CREATE TABLE `badwords`(
`id` int(3) NOT NULL auto_increment,
`word` text,
PRIMARY KEY (`id`),
KEY `id` (`id`))

假设我已经存储了以下单词

(1,ugly)
(2,yak)

现在我的访问者可能会发布一些包含其中一个坏词的链接,我愿意使用这样的东西。

$user = "http://www.this_ugly_site.com"; // visitor post this (ugly) word within

// i'm gonna try to find any of bad words stored in my table

$qry="select * from badwords where word='$user'"; // how to do it (find)
$result=mysql_query($qry) or die($qry);
if(mysql_num_rows($result)=='0'){

echo "Good URL";

}else{

while($line=mysql_fetch_array($result)){

echo "Bad URL";

}}

我不知道如何申请strpos,如果它真的很好的解决方案或者我可以使用其他东西!

或者我可以使用

$qry="select * from badwords where word LIKE '%$user%'";

但它看起来不安全,因为它将用户提供的值嵌入到您的 SQL 中

所以任何想法或帮助如何做到这一点〜谢谢

4

4 回答 4

3

如果你坚持做这样的事情,我会让 MySQL 为你做所有的工作。您需要做的是将操作数的顺序与您可能习惯在LIKE子句中使用它们的方式相反:

SELECT `word`
FROM `badwords`
WHERE '<user_input>' LIKE concat('%', `word`, '%')
LIMIT 1

基本的 PHP 代码类似于:

// User input
$user = "http://www.this_ugly_site.com";

// Find matching words
// Do NOT show mysql_error() or $query in a production environment!
$query = "
  SELECT `word`
  FROM `badwords`
  WHERE '".mysql_real_escape_string($user)."' LIKE concat('%', `word`,'%')
  LIMIT 1
";
$result = mysql_query($query) or die("MySQL Error: ".mysql_error()."\n".$query);

// Test for a match
if (mysql_num_rows($result)) {
  $row = mysql_fetch_assoc($result);
  echo "Bad URL (matches {$row['word']})";
} else {
  echo "Good URL";
}
于 2012-05-22T12:52:49.937 回答
2

您正在向后搜索字符串。我不确定我是否会使用 MySQL 来执行此操作;相反,我可能会将所有不好的词从表中拉出,然后搜索我的字符串,如下所示:

<?
$user_string = "http://www.this_ugly_site.com";

$query = "SELECT word FROM badwords";
$res = mysql_query($query);

$stringOkay = true;

while ($row = mysql_fetch_assoc($res))
{
    //use stripos for case insensitive matching
    if (stripos($user_string, $row['word']) !== false)
    {
        //this user string contains a bad word!
        $stringOkay = false;
        break;
    }
}

if ($stringOkay) echo "Good URL";
else echo "Bad URL";

正如 DaveRandom 在您的 OP 中评论的那样,使用这种搜索方法,您将提出很多误报和误报。稍微好一点的方法是使用正则表达式,但即使是那些也不是万无一失的。

例如,您可能想要阻止单词 'yak' bot 而不是 'kayak' 所以要完成此操作,您将使用带有单词描述符 (\b) 的正则表达式,并且您将有一个像这样的表达式: #(^|\b)yak(\b|$)#i,这也提供当你用这样的模式拼写“leet speak”时,你可以阻止像“ass”这样的东西,#a(55|$$)#i但同样,这可能会出现误报,因为有人可以输入a5$or a**。基本上,这是一个“难题”,您将需要一个更复杂的解决方案来获得完整的覆盖/保护。

于 2012-05-22T12:42:24.140 回答
2

你问了 3 个不同的问题:

  1. 我该如何使用strpos()

    这是一个带有三个参数的原生 PHP 函数。我鼓励您使用和学习PHP 文档。尽管如此,这里有一个例子:

    strpos($string, $bad_word);
    
  2. 有没有更好的办法?

    可能。但你所拥有的并不坏。strpos()是更快的字符串函数之一。如果您每秒有数千个坏词和大量请求,那么您可能希望研究缓存坏词而不是每次都查询 MySQL。但是,无需过早优化。现在,早点失败。那是当你发现一个坏词break在循环之外。

  3. 如何在 MySQL 中转义字符串?

    我鼓励您使用MySQLi扩展,然后使用mysqli->real_escape_string().

    例如:

    $qry = "SELECT * FROM badwords WHERE word LIKE '%" . $dbc->real_escape_string($user) . "%'";
    
于 2012-05-22T12:48:17.537 回答
1
$user = "http://www.this_ugly_site.com"; 
$qry="select word_column_name from badwords"; 
$badwords=mysql_query($qry);
if(badword($user,$badwords))
    echo "bad url";

function badword($user,$badwords)
{    
   foreach($badwords as $badword)
   {
     if(stristr($text,$badword))
     {
            return true;
     }
   }
   return false;
} 
于 2012-05-22T12:44:26.527 回答