我要创建数据库表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
中所以任何想法或帮助如何做到这一点〜谢谢
答案 0 :(得分: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";
}
答案 1 :(得分: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)的正则表达式,并且您将拥有如下表达式:{ {1}},这也可以让你在“leet speak”拼写时使用类似#(^|\b)yak(\b|$)#i
的模式来阻止像“屁股”之类的东西,但同样,这会受到假阴性的影响,因为有人可以输入{{1 }或#a(55|$$)#i
。基本上,这是一个“难题”,您将需要一个更复杂的解决方案来获得完整的覆盖/保护。
答案 2 :(得分:2)
您已经提出了3个不同的问题:
如何使用strpos()
这是一个本机PHP函数,它有三个参数。我鼓励你使用和学习PHP Docs。尽管如此,这是一个例子:
strpos($string, $bad_word);
有更好的方法吗?
可能的。但你拥有的并不坏。 strpos()
是更快的字符串函数之一。如果您每秒有数千个坏词和大量请求,那么您可能希望每次都查看缓存坏词而不是查询MySQL。但是,不需要过早优化。现在,早点失败。那是当您在循环中找到坏词,break
时。
如何在MySQL中转义字符串?
我建议您使用MySQLi扩展名,然后使用mysqli->real_escape_string()
。
例如:
$qry = "SELECT * FROM badwords WHERE word LIKE '%" . $dbc->real_escape_string($user) . "%'";
答案 3 :(得分: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;
}