使用PHP读取和搜索txt文件的问题
我正在写一个小脚本,用于检查用户是否在名为whitelist.txt的文件中有他的用户名。如果没有找到它的用户名添加。这是脚本:使用PHP读取和搜索txt文件的问题
$fh = @fopen("whitelist.txt", 'a+');
$stringData = $_POST[usr]. "\n";
if ($fh)
{
while (!feof($fh))
{
$buffer = fgets($fh);
if (strpos($buffer, $stringData) == TRUE)
echo "This username is already whitelisted.";
elseif (strpos($buffer, $stringData) == FALSE) {
fwrite($fh, $stringData);
echo "Username ". $stringData. " is now whitelisted.";
}
}
fclose($fh);
}
我现在得到的,如果我第一次输入一个新的用户名,一切都好。第二次输入一个新的用户名时,它会被复制。问题在继续:如果我输入一个现有的用户名,它会被添加两次,并显示“此用户名已被列入白名单”。没有显示。每个用户名都在一个新行中。
谢谢你的时间和帮助!
编辑添加:接受答案很好。作为对比,我在下面修改了你的代码,如果你想继续逐行阅读而不是一次阅读 - 文件不可能变得如此之大,以至于在一个块中这样做是一个问题,但做出这样的假设总是让我感到非常紧张。
我看到一对夫妇的问题,在这里:
即使当你发现文件中的用户名,你进行过文件的其余部分,让假阴性。尝试:
if (strpos($buffer, $stringData) == TRUE) {
echo "This username is already whitelisted.";
break;
}
你else if
将每当脚本找到一条线,不符合提交用户名,而不是当它到达了文件的末尾触发。您需要在循环之外移动该检查,以便仅添加一次新的用户名。总之,现在:
$fh = @fopen("whitelist.txt", 'a+');
$stringData = $_POST[usr]. "\n";
if ($fh)
{
$found = false;
while (!feof($fh))
{
$buffer = fgets($fh);
if (strpos($buffer, $stringData) == TRUE) {
echo "This username is already whitelisted.";
$found = true;
break;
}
if (!$found) {
fwrite($fh, $stringData);
echo "Username ". $stringData. " is now whitelisted.";
}
fclose($fh);
}
这个文件剂量有一个变得非常大的趋势:S所以我使用你的代码:D谢谢! – andreicek 2012-03-11 23:40:03
从字符串数据变量中除去\ n。这不会有帮助。 同时检查结果对从真或假strpos与===
:
strpos() === TRUE
由于0和虚假与==
同样的事情。
没有\ n everthing写在同一行。另一部分我不太明白:( – andreicek 2012-03-11 23:16:33
什么是这样的:
$file = 'whitelist.txt';
$contents = file_get_contents($file);
if (strpos($contents, $stringData) === FALSE)
{
$contents .= "\r\n" . $stringData;
file_put_contents($file, $contents);
echo 'Added ' . $stringData . ' to whitelist.';
}
else
{
echo 'Already whitelisted.';
}
是的,请注意,这是三个等号。您可能遇到的问题是== FALSE匹配的情况下,其中$ stringData是第一个结果(因此0,我们都知道FALSE == 0):)
如果存在部分匹配(例如,如果文件包含“foobar \ n”,则“bar \ n”会匹配),这不会导致误报吗? – 2012-03-11 23:32:37
经过测试,它的工作正常:D – andreicek 2012-03-11 23:37:44
@Phoenix是的,我认为你是对的。andreicek你可能想做一个preg_match并匹配整行。像preg_match('/^'.$ stringData。'$ /', $ contents) – 2012-03-11 23:46:26
没有挖掘太多进入这个代码的编写方式背后的原因,我会说,@marramgrass解决了最初的问题。不过,我建议使用file()
将文件读入数组。那么你可以做一个简单的检查,如下所示:
if(strtolower($_POST[usr]) == $Array[index])
{
echo 'Username is already whitelisted';
}
这样的逻辑是死的简单,你不处理strpos。
我不喜欢你已经打开的文件进行写入没有查清是否存在匹配或不
$username = "thegreatone";
$lines = file("yourfile.txt");
foreach($line as $no => $line) {
if(strstr($line,$username)) {
//Now start the hand
$fp = fopen('whitelist.txt', 'a+');
fwrite($fp, '\r\n'.$username);
fclose($fp);
//Since the search was true... no need to continue the loop
break;
}
}
尖叫出来使用的数据库。 – 2012-03-11 23:11:47
其他软件使用的文件,所以我坚持使用它。 – andreicek 2012-03-11 23:13:42
在这种情况下,您应该使用===不==,请参阅手册页为什么 – 2012-03-11 23:15:37