1

Somehow my conditional simply doesnt work. Once I click the button on my login form which is set to "post" and has the action defined as the below login script I only get directed to the script but not redirected as defined in my conditional statement. What is wrong with my code?

session_start();

$servername = "localhost";
$username = "root";
$password = "";
$database = "project";

$connection = mysqli_connect($servername, $username, $password, $database) or exit(header("location:maintenance.php"));

function login_check() {

    global $connection;

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

    $prepared = mysqli_stmt_init($connection);
    $request = mysqli_stmt_prepare($prepared, "SELECT id FROM members WHERE name = ? AND password = ?");
    mysqli_stmt_bind_param($prepared, "ss", $name, $password);
    $result= mysqli_stmt_bind_result($request);
    $rows_counter = mysqli_num_rows($result);
    mysqli_stmt_close($prepared);

    if ($rows_counter > 0) {
        $_SESSION['member'] = $name;
        header("location:../../success.php");
    }
    else {
        header("location:../../relogin.php");
    }
}
Asperger
  • 3,064
  • 8
  • 52
  • 100
  • Also the database is set. I assume maybe it cant access my query. No idea why and I cant even echo $rows_counter for debugging purposes. – Asperger Aug 21 '15 at 08:10
  • 1
    When you submit your for, will the `login_check()` be fired up? – KhorneHoly Aug 21 '15 at 08:13
  • @KhorneHoly it should, because my form has the action defined as my login_check.php file – Asperger Aug 21 '15 at 08:21
  • if you want to echo `$rows_counter` then put the following lines before the if statement: `echo $rows_counter;` `die();` – phpchap Aug 21 '15 at 08:23
  • @Asperger it `should` doesn't mean it `does`. Do what phpchap wrote down, if you get something echo`d out then your function will be called, else it won't. – KhorneHoly Aug 21 '15 at 08:26
  • @phpchap I get no output from $rows_counter or even $result. I remove the function() part included the opening and closing brackets, then under the else statement I added the echo/s. No success – Asperger Aug 21 '15 at 08:27
  • @KhorneHoly it seems no output from my echo – Asperger Aug 21 '15 at 08:29
  • I am debugging your code now, it is full of bugs, the problem is not even in your if statement, it is longer up. – Maytham Fahmi Aug 21 '15 at 08:29
  • @maytham-ɯɐɥıλɐɯ how did you debug it? – Asperger Aug 21 '15 at 08:31
  • @Asperger phpstorm and my brain, your statements is not corrected done and therefore it does not return any thing, therefore you keep returning to the same page – Maytham Fahmi Aug 21 '15 at 08:35
  • @maytham-ɯɐɥıλɐɯ now the issue is that the if statement doesnt work, only the else redirection. This means even though the username and password exists the row numbers seem to be always 0. At least that is what I suspect – Asperger Aug 21 '15 at 08:50
  • @Asperger Have you checked that $name and $password contain the values that you expect? Perhaps the $_POST values don't contain the correct values. Perhaps try replacing the $_POST values for these variables with hardcoded values to check your sql is working? – phpchap Aug 21 '15 at 08:55
  • I am reworking your code now and will post my suggestion so you can see it – Maytham Fahmi Aug 21 '15 at 08:56
  • @maytham-ɯɐɥıλɐɯ thats awesome. Thanks. – Asperger Aug 21 '15 at 09:00
  • I am out now soon will be back and post some thing – Maytham Fahmi Aug 21 '15 at 09:58
  • @maytham-ɯɐɥıλɐɯ sure thing. Thanks for your assistance – Asperger Aug 21 '15 at 10:00
  • Please never store passwords in plain text. If your storage (database) gets compromised, 'everyone' knows all the passwords. You really should hash the passwords and use salt with that (there are many Q&A's here on SO on this topic). – Marten Koetsier Aug 21 '15 at 12:57
  • I agree with Marten, my only suggestion here is before going to hash/salt your password, is while doing your development process, it is fine to work with plain text, you can develop a little hashing/salt function and added later when you are 100% sure every thing is working. – Maytham Fahmi Aug 21 '15 at 15:08

4 Answers4

1

After defining the function login_check(), you should also call it (if the conditions are right):

function login_check() {
    // your implementation as above
}

if (isset($_POST['name']) && isset($_POST['password'])) {
    login_check();  // actually call the function
}

As a side note, it is good practice to also explicetely close the connection before redirecting.

Edit

as KhomeHoly comments, only call the function when necessary...

Community
  • 1
  • 1
Marten Koetsier
  • 3,389
  • 2
  • 25
  • 36
  • You shouldn't just call the function everytime you land on this .php page. You should only call the function if the certain parameters are set and valid that are needed for that function. – KhorneHoly Aug 21 '15 at 08:27
  • Marten, if I call the function now then it runs before I triggered the forms button. – Asperger Aug 21 '15 at 08:30
  • @Asperger: the edit will do the trick: only call it if `name` and `password` are set. – Marten Koetsier Aug 21 '15 at 08:33
  • Hi marten, dont I automatically call the function if I click on my forms button? action="php/core/login.php" or do I have the wrong idea? – Asperger Aug 21 '15 at 08:33
  • @Asperger: The `action` parameter in the `form` tag specifies which script will be called, not which function within the script. – Marten Koetsier Aug 21 '15 at 08:35
  • @Asperger No, you don't! It will run the whole .php file, but only executes what your wrote within the file. You must call the function you define if you want to usw them. It's like you've built a room in a house but forgot the door. It's there, but nobody can access it – KhorneHoly Aug 21 '15 at 08:35
  • It semi works. For some reason I only get redirected to my else header. The if never gets executed. Is there something wrong in my prepared statement? I read the php documentation and it should be right – Asperger Aug 21 '15 at 08:44
1

You need to call your functions if you define them. Not doing so is like building a room within a new house but forgetting the door. It's there, but nobody can use or access it.

So what you need to do is the following:

// your script as it is right now

if (isset($_POST['name']) && isset($_POST['password'])) {
    login_check();  // actually call the function
}

With isset() you check if the certain $_POST parameters are set, but not validated. You should at least do a basic validation of the data to see if they are correct!

Something like this would work, depends on your requirements

if (isset($_POST['name']) && strlen($_POST['name') >= 4 && isset($_POST['password']) && strlen($_POST['password']) >= 4) {
    login_check();  // actually call the function
}

The code above would check if those paramters are set and check if name and password are at least 4 characters long. (I wouldn't accept usernames lower than 4 chars personally, passwords should be at least 8 for me)

Now of course this misses an correct error reporting and all that stuff, but I think that should give you the basic idea based on your quesiton.

KhorneHoly
  • 4,666
  • 6
  • 43
  • 75
  • I could even do some regex later to add some even better validation right? The issue im having is that the if statement doesnt work, I do get redirected to my else header though. Could it be that my prepared statement is wrong? I followed the php documentation on how those prepared statements in procedural methods work unless I missed something – Asperger Aug 21 '15 at 08:48
  • Of course you could, validation of everything that comes from a user is pretty important. Great that you're using prepared statements, they lower the risk of security breaches. My IDE tells me that the function `mysqli_stmt_bind_result()` is missing an parameter, you should have a look at it – KhorneHoly Aug 21 '15 at 09:32
  • I try to adhere to best practices as much as possible. Im pretty new to the realm of php but before I start coding cool things I want the basics right. Once I know all the procedural stuff I will convert everything to OOP – Asperger Aug 21 '15 at 10:01
1

Here is my input and approach to your code.

First of all before writing a solution and tell to much, it is always a good practice to make step by step code troubleshooting.

Before going and building a complete login system and put if statement or make prepare statement with inputs etc.

Make your solution in small working chops and put the puzzle together.

You question was focused on if statement and most of the help and answer was also focused on if statement which is nice, but the problem was not there.

I removed the if statement and a lot and just focused to see if I get some thing returned, I did not.

You $result= mysqli_stmt_bind_result($request); missed arguments, when that fixed, the next line missed also something else. I already there quit debugging.

I have rewrite your code and it works, what I did I have redefined the naming of variable so they are crystal clear to understand what is name, call it username, database username call it dbUser or dbUsername etc.

And if you want to check your code returning some thing or not, use var_dump($someVariable).

Last thing, before making a post form, you could create a dummy username and password in your database and inject that directly in your code like, just to see if every thing is working, and then move to your form:

$username = "user1";
$password = "1234";

The solution I did is just to demonstrate how to do it and not necessarily representation of the best logic, but it is up to you to find the correct logic and all depends on your strategy.

Here is my suggestion:

<?php
session_start();

$dbHost = "localhost";
$dbUser = "root";
$dbPass = "";
$dbName = "product";

$connection = new mysqli($dbHost, $dbUser, $dbPass, $dbName);

// Check connection
if ($connection->connect_error)
{
    header("location:maintenance.php");
    exit();
    // or for debugging, activate following line
    //die("Connection failed: " . $connection->connect_error);
}

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

//if username and password empty stop login
if (!$username || !$password)
{
    //do something, die is only example
    die ("Not all the fields were filled in");
} else
{
    login_check($username, $password);
}

function login_check($username, $password)
{
    global $connection;

    //sql statements is corrected, change field name to username
    $sql = "SELECT * FROM `members` WHERE `username` = ? AND `password` = ?";
    $stmt = $connection->prepare($sql);
    $stmt->bind_param("ss", $username, $password);
    $stmt->execute();
    $output = $stmt->get_result();
    $row = $output->fetch_array(MYSQLI_NUM);
    $stmt->close();
    //print what comes out in $row
    //print_r($row);

    //check if $row has data
    if ($row)
    {
        echo "success do something";
        $_SESSION['member'] = $username;
    } else
    {
        echo "fail do something";
    }
}
Maytham Fahmi
  • 31,138
  • 14
  • 118
  • 137
0

Always, always, always put exit() after header redirect call. Even in that case, it might solve your issue.

header("location:../../success.php");
exit();

Why?

Community
  • 1
  • 1
Kristian Vitozev
  • 5,791
  • 6
  • 36
  • 56
  • 1
    An explanation why this is neccessary would be helpfull for everybody that comes to this question – KhorneHoly Aug 21 '15 at 08:14
  • I still only get redirected to my script which I posted here (login.php) but the actual function doesnt seem to work, or at least the if statements are inactive because probably something is wrong with my query. Good tip though, I will keep it in mind! – Asperger Aug 21 '15 at 08:18