проблема с регистрацией и логином php, вы проверите мой код? если есть ошибка - PullRequest
0 голосов
/ 01 ноября 2018

У меня проблема с регистрацией и входом в систему (неопределенное смещение), и я смотрю на регистрацию. Есть ли какая-то проблема с моим кодом? Это форма регистрации, проблема в которой иногда сохраняется существующее электронное письмо, несмотря на то, что я написал функция для не отправки существующего электронного письма, которое находится внутри моего 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 голосов
/ 01 ноября 2018

Прежде всего, позвольте мне сказать, что сохранение паролей в виде простого текста в файле .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 возвращает логическое значение, поэтому вы присваиваете true или false этим двум переменным. Это не имеет значения, так как вы никогда не проверяете их, и в цикле вы перезаписываете вызов 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

Summery

На самом деле это довольно беспорядок. Под этим я подразумеваю, что вы использовали 3 разных способа открыть и получить доступ к данным файла. Вы использовали строковую константу PHP в некоторых местах, но не во всех. У вас был какой-то случайный код, где вы устанавливали вещи задолго до того, как они вам понадобились, а в некоторых случаях они вам могли и не понадобиться, поэтому вы тратили ресурсы на их установку.

Пожалуйста, не принимайте критику усердно, поскольку я не пытаюсь обидеть. Просто указав места, вы можете улучшить поток кода и упростить вещи. Главное, не унывать, чтобы эффективно программировать, нужно иметь не совсем спокойное отношение и стремление к постоянному самосовершенствованию. Даже после 9 лет программирования на PHP я все еще узнаю что-то новое, я узнал (и написал библиотеку вокруг него) что-то новое всего 2 дня назад ...

Как я сказал в начале, и, честно говоря, база данных фактически уменьшит объем кода, который вам нужен. Вначале может быть пугающим использование базы данных, но вы поймете, что это проще, чем делать это. Например, вы проверяете уникальность, вы можете установить уникальность поля в базе данных, тогда вам никогда не придется беспокоиться о дубликатах, а только обнаруживать ошибки для них.

Я бы предложил посмотреть PDO и подготовленные заявления password_hash и password_verify.

Последнее предупреждение: я не проверял ничего из этого, так что прости меня, если есть какие-либо опечатки ...

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...