0

I'm making a login script which fetches data from two tables. I understand that this error occurs when the statement returns FALSE AKA a boolean, but why is it returning false??? I made a function which works up to a point

    function loginall($username, $password)
{
    $db_host="localhost";
    $db_username="root";
    $db_password="";
    $db_name="name";
    $con=mysqli_connect($db_host, $db_username,$db_password, $db_name);
    $mysqli = new mysqli("$db_host","$db_username","$db_password", "$db_name");

    $qry = "SELECT username, password, level, active FROM businesses  WHERE username=? AND password=? 
    UNION SELECT username, password, level, active FROM employees WHERE username=? AND password=?";
    $stmt = $mysqli->prepare($qry);
    $stmt->bind_param("ssss", $u,$p,$uu,$pp);
    $u = $username;
    $p = $password;
    $uu = $username;
    $pp = $password;
    $stmt->execute();
    $result = $stmt->get_result();
    while($row = $result->fetch_array(MYSQLI_ASSOC))
    {
        return $row;
    } 
}

it works great until I try fetching more columns from the tables, or even trying to SELECT * from the tables. I read through other similar questions and found codes to get the error to appear, but no luck. Thank you!

Mar1AK
  • 29
  • 7
  • Based on your error message, one or more of $u, $p, $uu, or $pp is null. Echo them out to see which one. – Sloan Thrasher Apr 14 '17 at 04:01
  • The same query runs on my system – M A SIDDIQUI Apr 14 '17 at 04:07
  • @SloanThrasher can you please explain? The function works until I try to get more columns from the tables, which means these variables are OK ?? if I try to echo them it doesn't work because I get that error i'm talking about and a white page after the error, or it just logs me in but I need to get more columns when getting logged in. – Mar1AK Apr 14 '17 at 04:08
  • @MASIDDIQUI Have you tried SELECT * instead of selecting column names? – Mar1AK Apr 14 '17 at 04:09
  • It works on * as well as on columns names, do one thing just test the query from phpmyadmin or terminal – M A SIDDIQUI Apr 14 '17 at 04:11
  • @MASIDDIQUI The query it self should be OK with both the SELECT * or with selecting column names, which is what's driving me crazy. I'm not sure why it's giving me the error. So I mean the query will run in phpmyadmin because it is in fact correct, but I'll still get the PHP error when trying to login. – Mar1AK Apr 14 '17 at 04:13
  • @Mar1AK i am trying to get that error by altering it .. but to make sure test that query on php my admin – M A SIDDIQUI Apr 14 '17 at 04:16
  • Which line has the error? Can you mark it with a comment in your question's code? – Sloan Thrasher Apr 14 '17 at 04:34

2 Answers2

0

Your function will end/return as soon as it hits the first return statement in the loop (first iteration). You will need to build the complete array and then return it once.

This ought to do it:

if(!($stmt=$mysqli->prepare($qry))){
    return ["Prepare failed: ".mysqli_error($mysqli)];  // what does this say?
}elseif(!$stmt->bind_param("ssss",$u,$p,$uu,$pp)){
    return ["Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error];
}else{
    $u = $username;
    $p = $password;
    $uu = $username;
    $pp = $password;
    if (!$stmt->execute()){
        return ["Execute failed: (" . $stmt->errno . ") " . $stmt->error];
    }else{
        $result = $stmt->get_result();
        while($row = $result->fetch_array(MYSQLI_ASSOC)){
            $rows[]=$row;
        }
        return $rows;
    }
}

Try backticking all of your column names. LEVEL is a MySQL KEYWORD.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • i think $stmt is false as per the error – M A SIDDIQUI Apr 14 '17 at 03:52
  • He means that the while loop will not iterate more than once, because the function will exit after the first return, but that's not the case, the loop actually iterates through the full array. I'll try your suggestion, though. Thanks – Mar1AK Apr 14 '17 at 03:55
  • I am interested to hear how you can make your function continue to run after you call `return`. That would be a new one. – mickmackusa Apr 14 '17 at 04:00
  • @mickmackusa Your answer does make a lot of sense, but it's still giving the same error. Also the while loop iterates and the function doesn't exit after the first return. I tried your code and it gives me new errors, says "Undefined index level" for some reason it's not seeing the level column. – Mar1AK Apr 14 '17 at 04:01
  • @mickmackusa What you suggested is good, but it works without it, talking about question its not the answer – M A SIDDIQUI Apr 14 '17 at 04:08
  • @Mar1AK can you isolate the error using something like my answer code? – mickmackusa Apr 14 '17 at 04:18
  • @mickmackusa **LEVEL** it must be creating problem. Mar1AK just remove from LEVEL from your query – M A SIDDIQUI Apr 14 '17 at 04:28
  • @MASIDDIQUI I believe LEVEL and level aren't the same thing. Also the code worked even when level was in the code. It's just when I tried adding more columns or using the * selector. Good point however. – Mar1AK Apr 14 '17 at 04:41
  • @Mar1AK Unable to solve your issue but sql is case insensitive language and for it level and LEVEL are same – M A SIDDIQUI Apr 14 '17 at 04:43
  • @MASIDDIQUI changed it to levell in the tables and in the code. Still the same thing, thanks for your efforts man. – Mar1AK Apr 14 '17 at 04:46
  • @mickmackusa your code still gives the same error as before bro. "Notice: Undefined index: levell" – Mar1AK Apr 14 '17 at 04:46
  • @Mar1AK What kind of crazy symbols does password have in it and why are you actually pulling it from the database? – mickmackusa Apr 14 '17 at 04:57
  • @mickmackusa It's a md5 hash code. Also good point of why i'm pulling it from the database, I removed that column from the SELECT statement, I just added it when I was experimenting. Nothing changed after removing it from the SQL statement, though. – Mar1AK Apr 14 '17 at 05:05
  • @Mar1AK Are you connecting with a password? Do you have permissions? – mickmackusa Apr 14 '17 at 05:19
  • @Mar1AK Like Sloan, I'd like to know exactly which line is failing (which is why I tried to create so many breakpoints in my answer's code). – mickmackusa Apr 14 '17 at 05:25
  • @mickmackusa I'm connecting as root, without a password. Root has full permissions if I'm not mistaken. Your code should work really. I'm doing a var_dump($loginall) and the values are in the array but for some reason still gives me the undefined index levell error. this is the result of the var_dump { [0]=> array(3) { ["username"]=> string(5) "admin" ["levell"]=> int(1) ["active"]=> int(1) } } – Mar1AK Apr 14 '17 at 05:26
  • Are you var dumping inside the function or after it is returned? Is there more code to see? – mickmackusa Apr 14 '17 at 05:42
  • @Mar1AK I need to know where this error is generated. – mickmackusa Apr 14 '17 at 05:53
  • @Mar1AK I don't really know which line to address. Can you perhaps update your question to show which parts are successful, which parts are failing, and which line is causing an error? Is it after you are returning the array from the function? Is your main code expecting a key called "level" but you are feeding it an array that uses "levell"? I've invested enough time now, that I want to earn that green tick. – mickmackusa Apr 14 '17 at 06:30
  • @mickmackusa Your code is perfect, thanks for pointing out the return in the loop too. The issue was in the SQL. Thanks for your time. – Mar1AK Apr 14 '17 at 13:11
-1

Try this maybe bind_result() not get_result():

You might be wondering, why even use bind_result()?

This is strictly due to preference, as the syntax is considered to be more readable.

However, it should be noted that bind_result() may not be used with the * wildcard selector. It must contain explicit values

Here in this code using bind_result(), the values $usernameRow, $passwordRow, .... are form the database tebles:

.....
...
.
$stmt->bind_param("ssss", $username, $password, $username, $password);
$stmt->execute();
$stmt->store_result();
$numRows = $stmt->num_rows;
$stmt->bind_result($usernameRow, $passwordRow, $levelRow, $activeRow); 
if($numRows > 0) {
  while ($stmt->fetch()) {
    $u[] = $usernameRow;
    $p[] = $passwordRow;
    $uu[] = $levelRow;
    $pp[] = $activeRow;
  }
}
$stmt->close();
Mousa Alfhaily
  • 1,260
  • 3
  • 20
  • 38
  • I started to write this too, at first, but OP wants a single array returned, so it would have to be repackaged anyhow. – mickmackusa Apr 14 '17 at 04:22
  • @Mousa Alfhaily it just returns NULL when entering correct username and password. I set it to return NULL when it doesn't find a username and password match in the tables. – Mar1AK Apr 14 '17 at 04:35
  • @Mar1AK Sorry, i edited the answer, i did a mistake, the `bind_param` should be the username and the password that the user entered which are `$username, $password` but for both tables, so `bind_param("ssss", $username, $password, $username, $password)` – Mousa Alfhaily Apr 14 '17 at 06:41