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