0

I write a code to check duplicate user input in a txt file. when i click the button, it only checks from the second line in users.txt. which means, if i insert a duplicate the same as in line one, it doesnt work.

if(isset($_POST['button1'])) {
    $username1 = $_POST['username'];    
    $usernames = array();
    $users = fopen("users.txt", "r"); //open file
    while (!feof($users)) {
        $line = fgets($users, 4096); //read one line
        list ($firstname, $lastname, $username) = explode(" ", $line);
        if (empty($usernames)) {
            $usernames[] = $username1;
        } else {
            if (in_array($username1, $usernames)) {
                echo "Duplicate username: " . $username1 ;

            } else {
                $usernames[] = $username1;
            }
        }
    }
    fclose($users); #close file
}
?>
<form method="post">
               <input type="text" id="username" name="username">

                    <span id="err_u" style="color:red;visibility: hidden;">* Required</span>
                    <label for="username" >@gmail.com</label>
                    <input type="submit" name="button1" class="button" value="Check ID" />

</form>
TonyNew
  • 5
  • 4
  • Is your script saved with a `.php` extension? Is the server configured to serve PHP pages? Do other PHP scripts work on your server? – kmoser Dec 05 '20 at 23:09
  • it is saved with .php. my other php pages and scripts work well with the server. @kmoser – TonyNew Dec 05 '20 at 23:12
  • 1
    Does this answer your question? [PHP code is not being executed, instead code shows on the page](https://stackoverflow.com/questions/5121495/php-code-is-not-being-executed-instead-code-shows-on-the-page) – user3783243 Dec 05 '20 at 23:21
  • You also likely should use a DB for this, not text file. That's a different topic though. – user3783243 Dec 05 '20 at 23:22
  • @user3783243 yeah i know. but this is just a school exerciese – TonyNew Dec 05 '20 at 23:25
  • 1
    I'm not sure about the issue of the portion of the code that's printing to the page, but your check algorithm is wrong. You never actually use the submitted username from the form (`$_POST['username']`) to perform the check. You read from the file and you compare the value you read to the other values you've previously read from the file. Also, you should break out of the check as soon as you find a duplicate. Currently you'd continue reading the file all the way through. – El_Vanja Dec 05 '20 at 23:25
  • And this issue with the code displaying on the page, does it happen every time or only when you submit the form? – El_Vanja Dec 05 '20 at 23:26
  • 1
    The PHP showing is because PHP isn't processing. The `` is read as one element by browser. – user3783243 Dec 05 '20 at 23:30
  • @user3783243 Yeah, true. I figured it'd all display on the screen. – El_Vanja Dec 05 '20 at 23:35
  • @El_Vanja the code doesnt show at all now. but the submit button does not work – TonyNew Dec 05 '20 at 23:38
  • Have you read my lengthy comment? I point out what you're doing wrong. – El_Vanja Dec 05 '20 at 23:39
  • @El_Vanja yes I have. trying to fix it now. many thanks! – TonyNew Dec 05 '20 at 23:45
  • @El_Vanja touched on it, but you are checking for the username after reading just one line from text file, and you check the full array each time through the loop instead of just checking the one username you just read? And seems you will add the username from each line in text file twice. – Garr Godfrey Dec 06 '20 at 00:03

2 Answers2

0

change the code to this:

<?php
if (isset($_POST['button1'])) {
    $username1 = $_POST['username'];
    $usernames = array();
    $users = fopen("users.txt", "r"); //open file
    while (!feof($users)) {
        $line = fgets($users, 4096); //read one line

        list($firstname, $lastname, $username) = explode(" ", $line);
        $usernames[] = (string)$username;
    }

    if (empty($usernames)) {
        $usernames[] = $username1;
    } else {
        if (in_array($username1, $usernames)) {
            echo "Duplicate username: " . $username1;
        } else {
            $usernames[] = $username1;
        }
    }

    fclose($users); #close file
}
?>
<form method="post">
    <input type="text" id="username" name="username">

    <span id="err_u" style="color:red;visibility: hidden;">* Required</span>
    <label for="username">@gmail.com</label>
    <input type="submit" name="button1" class="button" value="Check ID" />

</form>
  • thanks for your help. in the file i used to test, there's no space in between a name or so. also tried PHP_EOL, result is the same – TonyNew Dec 06 '20 at 00:32
  • in the first iteration, you add new username1 to the array, because the usernames array is empty, so you need to fill the usernames array first then compare it with new submitted username1 – Hamid Alizadeh Dec 06 '20 at 00:43
  • @TonyNew I changed the code, now in the while loop first we have all usernames in the array then we check for duplication – Hamid Alizadeh Dec 06 '20 at 00:52
  • I am terribly sorry to bother you again. Thanks a lot for your code. I actually figured out the code myself! but when i tested it, the result is, when i click the button, it only checks from the second line in users.txt. which means, if i insert a duplicate the same as in line one, it doesnt work – TonyNew Dec 06 '20 at 01:00
0

You have some logic issues.

$usernames is never empty. So you can replace this


if (empty($usernames)) {
    $usernames[] = $username1;
} else {
    if (in_array($username1, $usernames)) {
        echo "Duplicate username: " . $username1;
    } else {
        $usernames[] = $username1;
    }
}

by this


if (in_array($username1, $usernames)) {
    echo "Duplicate username: " . $username1;
} else {
    $usernames[] = $username1;
}

and more, $username1 is the posted username, there are no reason to put it in the $usernames collection.

Then you can replace this


if (in_array($username1, $usernames)) {
    echo "Duplicate username: " . $username1;
} else {
    $usernames[] = $username1;
}

by this


if (in_array($username1, $usernames)) {
    echo "Duplicate username: " . $username1;
}

And more, you do not need collect the usernames. You only need to check the current value in the loop. If the value match with $username1, the username exists. Using a break we can terminate the loop and prevent memory leaks.

See the the code


if (isset($_POST[ 'button1' ])) {
    $username1 = $_POST[ 'username' ];
    $users     = fopen("users.txt", "r"); //open file

    while ( ! feof($users)) {
        $line = fgets($users, 4096); //read one line
        list ($firstname, $lastname, $username) = explode(" ", $line);

        if (strtolower($username) == strtolower($username1)) {
            echo "Duplicate username: ".$username1;
            break;
        }
    }

    fclose($users); #close file
}

Additionally i have some suggestions:

  1. use the comma (,) character and save the file as a csv (comma separated values) file. With comma, you prevent errors with names that contains spaces.
  2. try to write modular code. In this case, you can create a function called usernameExists that returns true if the username exists and false it not.
  3. to compare usernames apply the trim and strtolower over the values

Here the final code

<?php

function usernameExists($username1)
{
    $exists = false;
    
    if (file_exists('users.csv')) {
        $users = fopen("users.txt", "r");
        
        $username1 = trim($username1);
        $username1 = strtolower($username1);

        while ( ! feof($users)) {
            $line = fgets($users, 4096);

            list ($firstname, $lastname, $username) = explode(",", $line);
            
            $username = trim($username);
            $username = strtolower($username);

            if ($username == $username1) {
                $exists = true;
                break;
            }
        }

        fclose($users);
    }
    
    return $exists;
}

// the logic is very simply now
if (isset($_POST[ 'button1' ])) {
    $username1 = $_POST[ 'username' ];
    
    if (usernameExists($username1)) {
        echo "Duplicate username: ".$username1;
    }
}

?>