2012-03-11 96 views
0

我正在寫一個小腳本,用於檢查用戶是否在名爲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

回答

1

編輯添加:接受答案很好。作爲對比,我在下面修改了你的代碼,如果你想繼續逐行閱讀而不是一次閱讀 - 文件不可能變得如此之大,以至於在一個塊中這樣做是一個問題,但做出這樣的假設總是讓我感到非常緊張。


我看到一對夫婦的問題,在這裏:

即使當你發現文件中的用戶名,你進行過文件的其餘部分,讓假陰性。嘗試:

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

0

從字符串數據變量中除去\ n。這不會有幫助。 同時檢查結果對從真或假strpos與===

strpos() === TRUE 

由於0和虛假與==同樣的事情。

+0

沒有\ n everthing寫在同一行。另一部分我不太明白:( – andreicek 2012-03-11 23:16:33

1

什麼是這樣的:

$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

0

沒有挖掘太多進入這個代碼的編寫方式背後的原因,我會說,@marramgrass解決了最初的問題。不過,我建議使用file()將文件讀入數組。那麼你可以做一個簡單的檢查,如下所示:

if(strtolower($_POST[usr]) == $Array[index]) 
{ 
    echo 'Username is already whitelisted'; 
} 

這樣的邏輯是死的簡單,你不處理strpos。

0

我不喜歡你已經打開的文件進行寫入沒有查清是否存在匹配或不

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