【问题标题】:Best way to 'filter' user input for username [closed]为用户名“过滤”用户输入的最佳方法[关闭]
【发布时间】:2011-09-07 17:31:55
【问题描述】:

我有一个网站,允许用户创建一个“唯一 URL”,以便他们可以以 www.site.com/customurl 的形式传递给同事。

当然,我会进行检查以确保输入确实是唯一的,但我还想过滤掉大公司名称(受版权保护的名称等)和诅咒词之类的东西。为此,我的想法是构建一个 txt 文件,其中包含想到的每个可能的名称/单词的列表。我们所拥有的测试 txt 文件的文件大小不是问题,但我很好奇这是否是解决此问题的最佳方法。我认为数据库调用不如读取文本文件高效。

我的代码是:

$filename = 'badurls.txt';
$fp = fopen($_SERVER['DOCUMENT_ROOT'] . '/' .$filename, 'r'); 
if ($fp) { 
  $array = explode("\n", fread($fp, filesize($_SERVER['DOCUMENT_ROOT'] . '/' .$filename))); 
}

if(in_array($url, $array)) {
  echo 'You used a bad word!';
} else {
  echo 'URL would be good'; 
}

注意

我说的可能是前 100-200 家公司的名单,也许还有 100 个脏话。我可能是错的,但不要期望这个列表永远超过 500 字,更不用说 1000 字了。

【问题讨论】:

  • 我实际上会说使用 DB 效率更高——尤其是在文件越来越大的情况下。
  • 我相信你应该在你的数据库中使用一个表,它会更快地搜索,并且可以更容易地在你的脚本后端添加新的禁止名称。即使只有 500 个,也可以创建日志来计算或记录哪些用户正在使用哪些 url,1 个表可以用于多种用途......不要懒惰寻找快速解决方案,还有使用不同字符集和大写字母的单词呢
  • 我删除了最后一段,因为它离题且令人反感。
  • @NikiC - 我衷心感谢某些 SO 用户的帮助,如果冒犯所有人,但它是垃圾 (IMO),当用户继续投票时,我表示歉意,投反对票(可能是因为他们给出的答案被投反对票),甚至不提为什么。协作网站的重点是分享信息和建设性意见。如果有人不同意我的问题内容,​​我对此没有异议,但请花时间说明原因,而不是简单地单击鼠标并离开页面。

标签: php text fopen fread


【解决方案1】:

您可能认为数据库调用没有那么高效,但它的效率要高得多。数据库在数据上生成索引,因此它实际上不必遍历每个项目(正如in_array 在内部所做的那样)来查看它是否存在。您的代码将是O(n),数据库将是O(log n)...更不用说在每次页面加载时不必全部加载文件所节省的内存。 (见B-Tree Indexes)。

当然,500 个元素并不是很多。把它放在一个文件里不会有什么大不了的,不是吗?实际上,它会的。这不是一个很大的性能问题(数据库调用的开销将抵消文件的效率损失,因此它们在时间上应该大致相等)。但这是一个可维护性的问题。你今天说最多500字。当您意识到需要提供重复检测时会发生什么?也就是说,检查您的站点中是否存在现有 URL。无论如何,这将需要一个数据库查询,那么为什么不把这一切都集中在一个地方呢?

只需创建一个带有名称的表,为其编制索引,然后执行简单的 SELECT。它会更快。而且效率更高。并且更具可扩展性......想象一下,如果您达到 1gb 的数据。数据库可以处理得很好。读入内存的文件不能(你会用完 RAM)...

不要尝试像这样优化,Premature Optimization should be avoided。相反,实施干净且良好的解决方案,然后仅在应用程序完成后在必要时进行优化(并且您可以识别出慢的部分)...

还有一点值得考虑。如果 $url = 'FooBar';foobar 在文件中,则代码将失败。当然,您可以简单地在 url 上执行 strtolower,但何必呢?这是数据库的另一个优点。它可以进行不区分大小写的遍历。所以你可以这样做:

SELECT id FROM badnametable WHERE badname LIKE 'entry' LIMIT 1

只需检查没有匹配的行。无需执行COUNT(*) 或其他任何操作。您只关心匹配行的数量(0 好,!0 不好)。

【讨论】:

  • 文件被读入内存的好处。我说的是假设的最大文件大小为 10kB。
  • 为此目的设计和优化了数据库(嗯,这是它们的用途之一)。你可以实现自己的算法,但何必呢?只需使用数据库并完成它。您已经与应用程序的其余部分建立了连接,对吗?使用简单易行的解决方案(查询数据库更简单,特别是因为您需要对代码进行错误检查和边缘情况,但数据库会为您完成这些)...
  • 感谢您的更新。正如我上面提到的,我已经检查了重复的 URL(除其他外)并且有一个激活的 DB 连接以允许后续“插入”新 URL。
  • 好吧,那么真的没有什么能阻止你将数据放入数据库...如果你根本不使用数据库,我可以看到一个论点,但既然你是,那就重新- 使用连接。此外,如果文件像你说的那么小,那么任何一种方式都会很快,所以简短的回答是:别担心...
猜你喜欢
  • 2010-10-15
  • 1970-01-01
  • 2013-06-10
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 2013-07-21
  • 2016-10-25
  • 1970-01-01
相关资源
最近更新 更多