注册和登录php时出现问题,是否可以检查我的代码?

时间:2018-11-01 05:05:09

标签: php arrays login registration core

我在注册和登录显示(未定义的偏移量)方面都遇到了问题,请看注册我的代码是否存在问题?这是注册形式的问题,尽管我写了一个事实,有时它仍保存了现有的电子邮件一种不提交我的data.txt内部现有电子邮件的功能。很快这些功能将无法正常工作

<?php
if(isset($_POST['submit_reg'])){
    $var=file("data.txt");
    $userData = $_POST['email'] . " " . $_POST['password'] . "\r\n";
    $lines=0;
        $db = fopen("data.txt", "a+");
        foreach($var as $key=>$value){
            $user = (explode(' ', $value));
            if ($_POST["password"] === $_POST["confirm_password"]) {
                    //print_r($value);
                if (trim($user[0]) == $_POST['email']) {
                    $lines++;
                }
                break;

            } 
        }
            if($lines){
                    echo "The email is already exists ";
                }else{
                 fwrite($db,$userData."\r\n");
                 fclose($db);
                 echo "you are registered successfully ";
              }
} 
?>

这是我的登录表单,登录问题是出现错误的未定义偏移量12

<?php
if (isset($_POST['submit_log'])) {
    $email =isset($_POST['email']);
    $password =isset($_POST['password']);
    $file = explode( PHP_EOL, file_get_contents( "data.txt" ));
    $auth = false;
 foreach( $file as $line ) {
    list($email, $password) = explode(" ", $line);

    if ($_POST['email'] == $email && $_POST['password'] == $password) {
        $auth =true;
        break; 
    }
}
        if($auth) {
            echo "Login successfull!";
        } else {
            echo "Invalid username or password";
        }
    }
?>

1 个答案:

答案 0 :(得分:1)

首先让我说一下,将纯文本密码存储在.txt文件中可能不是构建longin系统的最佳方法。 (无论如何都是免责声明)。

未定义的偏移量(仅是猜测)

那表示我看到了一些可以改善您的代码的地方。我对错误没有更多细节的猜测是,您可能在文件末尾拉出一个空数组,通常在末尾留下一个挂起的行(最后一行没有其他任何内容的新行)。一旦您在空间['']上第二次爆炸它,它可能会变成类似这样的东西。然后,您尝试使用list来访问它,这将为您提供未定义的偏移量。

您可以使用array_filter并可能进行修整,而不是这样做:

 $file = explode( PHP_EOL, file_get_contents( "data.txt" ));

您可以尝试(已经使用此功能时应该知道)

 $file = file( "data.txt", FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES ));

文件功能,获取一个文件,并根据行返回将其分成一个数组。因此,这取代了explode和file_get_contents。

然后它有2个(按位)标志,您可以使用:

  

数组文件(字符串 $ filename [,int $ flags = 0 [,资源 $ context ]] ])

     

将整个文件读入数组。

     

FILE_IGNORE_NEW_LINES

     

在每个数组元素的末尾省略换行符

     

FILE_SKIP_EMPTY_LINES

     

跳过空行

http://php.net/manual/en/function.file.php

这些代替了为空行过滤数据(您没有做的事情)。当然,这是您创建的文件,但您永远不知道何时会出现错误的行返回。

非唯一条目

if(isset($_POST['submit_reg'])){
    $var=file("data.txt");
    $userData = $_POST['email'] . " " . $_POST['password'] . "\r\n";
    $lines=0;
    $db = fopen("data.txt", "a+");
    foreach($var as $key=>$value){
        $user = (explode(' ', $value));
        if ($_POST["password"] === $_POST["confirm_password"]) {
   //NOTE: the uniqueness check only happens when the confirm password matches
            if (trim($user[0]) == $_POST['email']) {
                $lines++;
            }
            break;

        } 
    }
    if($lines){
        echo "The email is already exists ";
    }else{
  //NOTE:yet you save it no matter if that is the case
        fwrite($db,$userData."\r\n");
        fclose($db);
        echo "you are registered successfully ";
    }
} 

您的唯一性检查仅在确认密码与密码匹配时起作用,但是当需要保存数据时,将不进行检查。与其将检查添加到保存位周围,不如将整个内容包装在此确认测试中,因为在检查文件之前,这两项都是已知的:

在这里我为您做了一些修改

if(isset($_POST['submit_reg'])){
    if ($_POST["password"] === $_POST["confirm_password"]) {

        //VERIFY AND SANITIZE user input, if you put junk in you get junk out

        $password = trim($_POST['password']);
         //again use something better then die
        if(empty($password))die('Password cannot be empty'); 
         //because you split on space, you cannot allow it in inputs
        if(preg_match('/\s+/', $password)) die('Password cannot contain spaces'); 

        $email = trim($_POST['email']);
        if(empty($email))die('Email cannot be empty'); 
        //you may want to validate using something better
        if(preg_match('/\s+/', $email )) die('Email cannot contain spaces'); 

        //Use the flags
        $var=file("data.txt", FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES);

        //for duplication we only care if there is 1 previous entry
        //which is enough to say its a duplicate
        $exists=false;

        foreach($var as $key=>$value){
            $user = explode(' ', $value);
            if (trim($user[0]) == $email) {
                //we found a match this is enough to call it a duplicate
                $exists = true;
                break;
            }

        }

        if($exists){
            echo "The email is already exists ";
        }else{
            file_put_contants("data.txt", $email." ".$password.PHP_EOL, FILE_APPEND);
            echo "you are registered successfully ";
        }
    }else{
        echo "Confirm password must match password";
    }
} 

其他内容

这些也不正确:

$email =isset($_POST['email']);
$password =isset($_POST['password']);

Isset返回一个布尔值,因此您要为这两个变量分配truefalse。没关系,因为您从不检查它们,并且在循环中您可以通过调用list()来覆盖它们。但是,仅仅因为“无关紧要”并不意味着它是正确的。

这些确实应该是这样的:

if(!isset($_POST['email'])) 
    die("no email"); //dont use die but do some kind of error message

if(isset($_POST['password']))
    die("no password"); //dont use die but do some kind of error message

摘要

真的是一团糟。我的意思是,您使用了3种不同的方式来打开和访问文件数据。您在某些地方(而非全部)使用了PHP行常量。您有一些乱七八糟的代码,在需要它们之前就已经进行了设置,在某些情况下,您可能不需要它们,因此浪费了资源来设置它们。

请不要用力批评,因为我不是要冒犯。只需指出位置,就可以改善代码流并简化事情。重要的是不要灰心,要有效地进行编程,您必须具有不屈不挠的态度和不断自我完善的动力。即使经过9年的PHP编程,我仍然一直在学习新知识,但我还是在两天前学习了新知识(并围绕它编写了一个库)...

正如我在一开始所说的,老实说,数据库实际上会减少所需的代码量。刚开始使用数据库可能令人生畏,但是您会发现这样做比以前更容易。一个示例是检查唯一性,您可以将一个字段在数据库中设置为唯一,这样您就不必担心重复项了,只需捕获错误即可。

我建议调查PDO和准备好的语句password_hashpassword_verify

最后的警告是我没有测试任何一个,所以请原谅我有错别字...

希望有帮助。