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


Problems with reading and searching thru txt file with PHP

我正在写一个小脚本,检查用户的用户名是否在名为whitelist.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);
    }

如果我第一次输入一个新用户名,我现在得到的一切都好。第二次输入新用户名时,它会被复制。问题还在继续:如果我输入一个现有的用户名,它会被添加两次,并且不会显示消息"This username are ready whitelisted."。每个用户名都在一个新行中。

感谢您的时间和帮助!

编辑添加:接受的答案很棒。作为对比,我在下面修改了你的代码,以防你想继续逐行阅读,而不是一次全部阅读——文件不太可能变得太大,以至于在一个块中阅读是一个问题,但做出这种假设总是让我有点紧张。


我看到了几个问题,在这里:

即使你在文件中找到了用户名,你也会继续浏览文件的其余部分,得到假阴性。尝试:

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

这样的东西怎么样:

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

从字符串数据变量中删除。这无济于事。同时使用===:检查strpos的结果是否为真或假

strpos() === TRUE

由于0和false与==是相同的。

如果不深入研究这段代码编写方式背后的原因,我会说@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;    
    } 
}