1

I've been trying to write a PHP program that gives users the ability to register for an account and login once registered. I've managed to prevent the registration of multiple usernames and store all registered usernames and the corresponding passwords in a SQL table, but I'm trying to get login working by verifying passwords, and PHP doesn't seem to be recognizing anything from SQL. I've tried countless variations of mysqli_fetch_array and mysqli_fetch_assoc to no avail. Entirety of PHP code is posted below, with comments specifying the most relevant parts.

<?php session_start(); ?>
<html>
<head>
  <title>Test Form</title>
</head>

<body>
<link rel="stylesheet" type="text/css" href="main.css" />

<?php
include('mydbinfo.php');

$conn = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
if ($conn->connect_error) {
    echo("<font color='red'><p>Unable to connect to the database system</font>"."<font color='red'>Please try later.</font></p>");
    exit();
}

if($_POST["email"].value == "" or $_POST["password"].value == "") {
    print("<font color='red'><p>Sorry, you must enter values into each field.</font></p>"); 
} else {
    $mail = $_POST["email"];
    $_SESSION["sessUsername"] = $mail;
    $pass = $_POST["password"];
    $query = "SELECT user_password FROM logins WHERE email='$mail'";

    $result=mysqli_query($conn,$query);

    while($name = mysqli_fetch_array($result)) {
        array_push($names,$name['email']);

        for($n = 0; $n < count($names); $n++) {
            if($names[$n] == $name['email']) {
                $names++;
            }
        }

    }

    //Number of instances of SQL query result found in table.
    $count = mysqli_num_rows($result);

    if($count > 0) {

        //Supposed to contain password which corresponds to a given user ID.
        //This is the main issue.
        $new=mysqli_fetch_array($result);

        if($pass == $new) {
            print "<font color='red'><p>Welcome back, $mail!</p></font>";
        } else {
            print "<font color='red'>Your reservation was invalid.</font>";
            print($pass);
            print($result);
        }

    } else {
      echo "<font color='red'>Not found in table.</font>";
    }
}
?>

</body>
</html>
<?php>
6
  • Bolding doesn't work in a code block. Commented Jul 12, 2015 at 0:32
  • I don't think it is a good idea to bold code. Maybe you could add a comment before to say it is the most relevant part to the question, but it doesn't make it very readable with the code formatting of stackoverflow. Commented Jul 12, 2015 at 0:33
  • Wow that is embarrassing. It's "//Number of instances of SQL query result found in table." to the end that's really relevant, is there any other way to signify that? Commented Jul 12, 2015 at 0:34
  • I removed the attempts at bolding, the most relevant portions are commented. Commented Jul 12, 2015 at 0:36
  • I really don't understand this code. Your SQL query selects only passwords, but you try to build an array of email addresses from the returned data. Then when you have read all the data, you try to read a password from the result set, which will fail because there's no data left. Lastly, you then compare the array you tried to get from the result set with the string that the user has supplied. Commented Jul 12, 2015 at 0:37

3 Answers 3

2

When you fetch, you fetch an entire row (or an entire dataset).

In your case, you used a while loop to traverse through all rows. After that, you fetch another row again, but that won't work, because you have already fetched all rows using the loop.

Moreover, you compare the array you get (the entire row) with $pass, which of course won't work either.

So, this snippet:

$new=mysqli_fetch_array($result);
if ($pass==$new)
{
print "<font color='red'><p>Welcome back, $mail!</p></font>";
}

Should just be

if ($name['user_password'] == $pass) 
{
  print "<font color='red'><p>Welcome back, $mail!</p></font>";
}

$name is the variable in which you read the row(s) that match the e-mail address, so by changing the code as I suggested makes your code use the last password that matches.

After that, there are other issues to resolve. First of all, when logging in, you shouldn't need a while loop. Hopefully there is only one account that matches, and you should take precautions to make sure you cannot create duplicate accounts in the first place.

Also $name is not the best name for that variable, since it contains an entire row, with a name and password in it.

Also, I noticed that the query doesn't return the name or e-mail at all, so the loop that verifies them probably doesn't work either. So maybe it's a good idea to have another close look, or even start over. After all, you've been experimenting and although that is very informative, it also makes a mess of the code. Sometimes it's better to start over and put the knowledge you gained to use to build a new and improved version.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much. You're right, this code has gone through several iterations and is a bit messy, but the main issue was that I was comparing the entire array to the user's provided password. I fixed that and it is now doing what I wanted. Thanks again.
1

Just to complement the answer given by GolezTrol, I think you should consider reading about prepared statements, it is a simple way to prevent SQL injection that is a major threat in your code.

You can simply check if the combination email:password exists by simply executing this query:

SELECT email FROM logins WHERE email=? AND user_password=?

If you have any rows in your result, the login credentials are correct. With this query your are set to do prepared statements, read this.

Comments

0

GolezTrol's answer and the additional information provided by joaomlap's answer do a great job of answering this question. I just thought I'd touch on a few other things that might not be causing frustrations as of now, but eventually they might.


First - The <font> and <p> tags are not correctly ordered in the following lines of code:

echo("<font color='red'><p>Unable to connect to the database system</font>"
      ."<font color='red'>Please try later.</font></p>")

print("<font color='red'><p>Sorry, you must enter values into each field.
       </font></p>");

You should switch around the opening <font> and <p> tags to look like:

echo("<p><font color='red'>Unable to connect to the database system</font>"
      ."<font color='red'>Please try later.</font></p>")

print("<p><font color='red'>Sorry, you must enter values into each field.
       </font></p>");

Better yet, you should give the <p> tags an id like <p id='red-text'> and edit your main.css stylesheet to change the text color of the red-text ids. Thus eliminating the need for the <font> tags all together.


Second - All <link> tags should be located between the opening and closing <head> tags and below the <title> tag, if a <title> tag is present.

[The <link> tag] goes only in the head section, but it can appear any number of times.
- From: HTML link tag - W3Schools

So your code:

<head>
  <title>Test Form</title>
</head>

<body>
  <link rel="stylesheet" type="text/css" href="main.css" />
  <!-- more code -->
</body>

Should be changed to:

<head>
  <title>Test Form</title>
  <link rel="stylesheet" type="text/css" href="main.css" />
</head>

<body>
<link rel="stylesheet" type="text/css" href="main.css" />
<!-- more code -->
</body>


Third - What's up with the dangling <?php tag at the end of your code? Only when used in a file of pure php code, can the benefits of not closing a <?php tag be reaped.

If a file is pure PHP code, it is preferable to omit the PHP closing tag at the end of the file. This prevents accidental whitespace or new lines being added after the PHP closing tag, which may cause unwanted effects because PHP will start output buffering when there is no intention from the programmer to send any output at that point in the script. - The PHP Manual

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.