1

I need to do a Login form with PHP an SQlite. Registration works, and I can select all created users and echo them. When I try to check if username and password, which I get by $_POST, are matching: it echoes that I'm logged in now. But when I type in a wrong user/pw, it echoes the "invalid"-string, but there's also the following error:

Notice: Undefined variable: row in D:\xampp\htdocs\phpProjektSnippets\blogLogin.php on line 17

Line 17 is where I've got the if($row['username'] ...

This is my code:

$db = new PDO('sqlite:mysqlitedb.db');
$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

$username = $_POST['username'];
$password = $_POST['password'];

$sql = "SELECT * FROM users WHERE user_name = :name AND user_password = :pass";
$statement = $db->prepare($sql);
$statement->execute(array('name' => $username, 'pass' => $password));

try {
    $statement = $db->prepare($sql);
    $statement->execute(array('name' => $username, 'pass' => $password));

    foreach ($statement as $row);

    if ($row['user_name'] == $username && $row['user_password'] == $password){
        echo "Welcome " .$row['user_name']. ", You are now logged in.<br/ >";
    }else{
        echo "User Name or Password is invalid";
    }  
}
catch(PDOException $e) {
    echo "Something went wrong: ".$e->getMessage();
}

What's wrong here?

MichelleH
  • 41
  • 2
  • 10
  • 1
    try where user_name == '$username' – Mark Ng Nov 22 '15 at 13:45
  • Thanks for your help, but unfortunately it doesn't get better... The error still exists – MichelleH Nov 22 '15 at 13:50
  • hey, make sure your column name is correct. is it username or user_name? – Mark Ng Nov 22 '15 at 14:03
  • Hexaholic answer is correct below, as for your updated question, there is nothing wrong, maybe your return no result that is why no result. – Mark Ng Nov 22 '15 at 14:34
  • Doesn't work either... I want to get username and his password and see if they match. If they don't, there's an echo which says "wrong username and/or password". But I don't get this one... – MichelleH Nov 22 '15 at 14:58
  • I have tried simulating it on my machine and its working, perhaps you could post more of your codes including the echo wrong username... part? – Mark Ng Nov 22 '15 at 15:00
  • This is all of my code! it doesn't echo anything, I guess, he just can't find any user with this name and pw (although I looked it up in my db and it DOES exist...) I didn't do the "echo wrong username"-part yet, because I first just want to see if the sql-stmt and so on would work or if there's an error... – MichelleH Nov 22 '15 at 15:08
  • try manually creating on new user, do not hash the password, then try simply $password=$_POST['password'](for this testing purpose only), then try again by using the new credentials you created without hash, if u get result, then its your hash issue. – Mark Ng Nov 22 '15 at 15:13
  • I tried it now without hash (see my edited code in the question). If I put in my form an existing user with his pw, it echoes the username, like it should. But if I put in an existing user with wrong pw, it doesn't echo anything - shouldn't it echo the "Something went wrong"-part? – MichelleH Nov 22 '15 at 15:23
  • I write you something to get started. wait awhile and see below answer. – Mark Ng Nov 22 '15 at 15:28
  • i think I know what you meant now. Change the foreach part to '$row = $statement->fetch();', see edited. because foreach is not valid for empty result. wonder why I didn;t get the error like you though. – Mark Ng Nov 23 '15 at 09:15

3 Answers3

2

First of all, you should not use an SQL query that looks like yours. It is vulnerable for SQL injections and thereby unsafe!

Please read the answers on How can I prevent SQL-Injection in PHP for some very helpful tips on how to do it right.

The problem is that you append to the SQL string whatever the user submits to the server - that might be malicious code that gives an attacker access to your database or deletes data or other bad things might happen. See the link above for more information.

In your case, the code would look like this:

<?php
    $db = new PDO('sqlite:mysqlitedb.db');
    $db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

    $username = $_POST['username'];
    $password = md5($_POST['password']);

    $sql = "SELECT * FROM users WHERE user_name = :name ";

    try {
        $statement = $db->prepare($sql);
        $statement->execute(array('name' => $username));

        foreach ($statement as $row){
           echo $row['user_name'] . '<br />';
        }
    }
    catch(PDOException $e) {
        echo "Something went wrong: ".$e->getMessage();
    }
?>

Edit: Since you configured PDO with $db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ) to throw exceptions in case of an error, you should also catch them. I added the try/catch to the code.

Hexaholic
  • 3,299
  • 7
  • 30
  • 39
  • Hi, thanks for your help. Security isn't necessary here since it's a school project and we're just learning the basics. It works now, thanks a lot! I guess I'm coming back if I get another error - I'm a sysadmin and can't understand those thing at all... :) – MichelleH Nov 22 '15 at 14:02
  • 1
    @MichelleH Glad I could help. But please, *never* say "security isn't necessary". As you can see, it's just a few lines of code that improve your program a lot. It's better to learn it the right way from the beginning, especially as this is a school project. – Hexaholic Nov 22 '15 at 14:06
  • Yeah, sure :) One more question - I knew I couldn't do it alone... I want to do the sql statement this way so I can check if the username and the password are matching, but I get an error... I updated my question so you can see my code there. – MichelleH Nov 22 '15 at 14:14
  • Hm, and if I wanted to get username and his password and see if they match, how would the code be? If they don't match, there would be an echo which says "wrong username and/or password"... I don't get those things at all ._. – MichelleH Nov 22 '15 at 14:59
2

Adding to Hexaholic answer and further to your question.

This line catch your code error

catch(PDOException $e) {
    echo "Something went wrong: ".$e->getMessage();
}

If you want to write error in case of invalid user credentials, use if true...else...statement.

if(some argument){
    //do something if the argument result is true;
    }else{
    do something if the argument is not true;}

So your code should be something like this.

<?php
$db = new PDO('sqlite:mysqlitedb.db');
$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE user_name = :name AND user_password = :pass";

try {
    $statement = $db->prepare($sql);
    $statement->execute(array('name' => $username, 'pass' => $password));
    $row = $statement->fetch();
        if ($row['user_name'] == $username && $row['user_password'] == $password){
            echo "Welcome " .$row['user_name']. ", You are now logged in.<br/ >";
        }else{
            echo "User Name or Password is invalid";
        }           
}
catch(PDOException $e) {
    echo "Something went wrong: ".$e->getMessage();
}
?>

And if this is working, remember to rectify your hashing issue.

Maybe this picture can better help you understand for the code above

Wrong password output. wrong password

Correct password output. correct password

Mark Ng
  • 200
  • 3
  • 11
  • Hm, if I type in a user and his pw, it echoes the username - so this works. BUT: if I type in a wrong pw, I get the following error and echo: Notice: Undefined variable: row in D:\xampp\htdocs\phpProjektSnippets\blogLogin.php on line 20 User Name or Password is invalid --> line 20 is where you do the "if ($row['username']); – MichelleH Nov 22 '15 at 15:58
  • The error you get is that $row is not set, try copy and paste the entire code from foreach... onwards. you might have missed out something, edit: refresh my answer first, I have made some changes to better reflect what is going on – Mark Ng Nov 22 '15 at 16:01
  • Another question - you type those 2 lines with $statement twice; once after $sql= and once in try{}. Are both necessary or could I delete one? – MichelleH Nov 22 '15 at 16:05
  • That is my mistake, didn't delete away while copying yours, see edit. – Mark Ng Nov 22 '15 at 16:10
  • Okay, but how could I set $row so I don't have this error anymore? – MichelleH Nov 22 '15 at 16:20
  • i just did a simulation on my machine again, nothing went wrong and no error, copy the entire code over and try. – Mark Ng Nov 22 '15 at 16:23
0

Trouble is with semicolon in this line: foreach ($statement as $row);

Foreach simply does nothing instead of subsequent if.

Thinkeye
  • 888
  • 12
  • 22