使用PHP读取和搜索txt文件的问题

使用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); 
    } 

我现在得到的,如果我第一次输入一个新的用户名,一切都好。第二次输入一个新的用户名时,它会被复制。问题在继续:如果我输入一个现有的用户名,它会被添加两次,并显示“此用户名已被列入白名单”。没有显示。每个用户名都在一个新行中。

谢谢你的时间和帮助!

+1

尖叫出来使用的数据库。 – 2012-03-11 23:11:47

+0

其他软件使用的文件,所以我坚持使用它。 – andreicek 2012-03-11 23:13:42

+1

在这种情况下,您应该使用===不==,请参阅手册页为什么 – 2012-03-11 23:15:37

编辑添加:接受答案很好。作为对比,我在下面修改了你的代码,如果你想继续逐行阅读而不是一次阅读 - 文件不可能变得如此之大,以至于在一个块中这样做是一个问题,但做出这样的假设总是让我感到非常紧张。


我看到一对夫妇的问题,在这里:

即使当你发现文件中的用户名,你进行过文件的其余部分,让假阴性。尝试:

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); 
    } 
+0

这个文件剂量有一个变得非常大的趋势:S所以我使用你的代码:D谢谢! – andreicek 2012-03-11 23:40:03

从字符串数据变量中除去\ n。这不会有帮助。 同时检查结果对从真或假strpos与===

strpos() === TRUE 

由于0和虚假与==同样的事情。

+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):)

+1

如果存在部分匹配(例如,如果文件包含“foobar \ n”,则“bar \ n”会匹配),这不会导致误报吗? – 2012-03-11 23:32:37

+0

经过测试,它的工作正常:D – andreicek 2012-03-11 23:37:44

+2

@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;  
    } 
}