我有一个网站,允许用户创建“唯一网址”,以便他们可以通过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了。
答案 0 :(得分:4)
您可能认为数据库调用效率不高,但效率更高。数据库生成数据的索引,因此它实际上不必迭代每个项目(如in_array
内部执行)以查看它是否存在。您的代码将为O(n)
,数据库将为O(log n)
...更不用说不必在每次页面加载时完全加载文件而节省内存。 (见B-Tree Indexes)。
当然,500个元素并不是很多。将它粘在文件中并不是一件大事,不是吗?实际上,它会。这不是一个很大的性能问题(数据库调用的开销将抵消文件的效率损失,因此它们应该在时间上大致均匀)。但这是一个可维护性的问题。你今天说500字是最大的。当您意识到需要提供重复检测时会发生什么?也就是说,检查您网站中是否存在现有网址。这无论如何都需要数据库查询,为什么不在一个地方完成所有工作呢?
只需创建一个包含名称的表,将其编入索引,然后执行简单的SELECT。它会更快。并且效率更高。更具可扩展性...想象一下,如果你达到1GB的数据。数据库可以处理这个问题。读入内存的文件不能(你的RAM用完了)......
请勿尝试优化,Premature Optimization should be avoided。相反,实施干净且良好的解决方案,然后在应用程序完成后仅在必要时进行优化(并且您可以识别缓慢的部分)......
值得考虑的另一点。如果$url = 'FooBar';
和foobar
在文件中,则代码将失败。当然,你可以在网址上做strtolower
,但为什么要这么麻烦?这是数据库的另一个优点。它可以进行不区分大小写的遍历。所以你可以这样做:
SELECT id FROM badnametable WHERE badname LIKE 'entry' LIMIT 1
然后检查没有匹配的行。没有必要做COUNT(*)
或其他任何事情。你关心的只是匹配的行数(0表示好,!0表示不好)。