PHP未正确读取文件



这是我的代码:

<?php
$pass = $_GET["pass"];
$user = $_GET["user"];
$next = false;
$file = fopen("info.txt", "r") or die("Something went wrong.");
// Output one line until end-of-file
while(!feof($file)) {
if ($next == true and $pass === fgets($file)){
echo "true";
$next = false;
} else {
echo "false" . "<br>";
$next = false;
}
if (fgets($file) == $user) {
$next = true;
}
}
fclose($file);
?>

这是info.txt

ch1ck3n
kodero1029

注意,这只是一个虚构的密码

例如,我们转到包含此代码的我的网站,https://ch1ck3n.com/login/auth/auth.php?user=ch1ck3n&pass=kodero1029

并且它打印假两次。我正在使用php和一个简单的txt文档制作一个登录系统。php代码逐个读取txt文件行,如果一行与用户名匹配,则意味着密码在下一行。但如果你看到了,去网站,它会打印两次假。CCD_ 2变量用于指示下一行是密码。

怎么了

您的问题是因为:

if (fgets($file) == $user) {
$next = true;
}

为什么这是错误的

这是$next为真的唯一方法,但您有$user = $_GET["user"] //ch1ck3n,但如果您查看手册,它会指出:

fgets
返回从句柄指向的文件读取的长度不超过1字节的字符串。如果文件指针中没有更多的数据可读取,则返回FALSE。

另请参阅:

读取长度为-1字节或换行符(包含在返回值中(时,读取结束

(我的括号(

因此,fgets的返回值是一个包含行尾的字符串,并将其与没有行尾的文本字符串ch1ck3n进行比较。因此,$next永远不会为true,因此对于文件的每一行,if/else语句都将返回false选项。

解决方案:

从字符串中提取换行符:

if (trim(fgets($file)) === $user) {
$next = true;
}

对于您使用fgets的所有场合,都需要执行相同的操作。

安全注意事项:

正如评论中所提到的,你处理这个问题的方法re:security绝对是不正确的做法。您应该使用POST请求、数据库引用或SESSION cookie来安全地将凭据数据与脚本关联。

不要在URL中发送敏感信息,因为无论是否使用https:Link
,这都是不安全的

Felipe Duarte 评论

循环的每次迭代读取两行。因为你只有两行(也许是三行?(,这意味着在一次迭代中你就完成了。这样做:

<?php
$pass = $_GET["pass"];
$user = $_GET["user"];
$next = false;
$file = fopen("info.txt", "r") or die("Something went wrong.");
// Output one line until end-of-file
while(!feof($file)) {
$line = rtrim(fgets($file)); //Newline is included in the fgets result
if ($next == true && $pass === $line){
echo "true";
$next = false;
} else {
echo "false" . "<br>";
$next = false;
}
if ($line === $user) {
$next = true;
}
}
fclose($file);

两次都为false的原因(可能(是因为文件末尾可能有一行空行。

最新更新