0

The above error keeps coming up instead of redirecting to index.php

The code should start an admin user session on index.php. It was originally based on MySQL then I used MYSqli

<?php

$a = $_POST["username"];
$b = $_POST["password"];


$conn = new mysqli("localhost", "root", "", "...");


$query = $conn->query("SELECT * FROM users WHERE username='$a' AND          password='$b' AND isadmin=1");

$result = mysqli_query($conn, $query) or die(mysqli_error($conn));
$num_rows = mysqli_num_rows($result);


session_start();


if  ($result)
{
$_SESSION["admin"] = $_POST["username"];

header ("Location: index.php");
}

elseif (!$result)
{
$_SESSION["gatekeeper"] = $_POST["username"];
header ("Location: index.php");
}

else
{
jsmith
  • 47
  • 2
  • 10
  • 1
    Also, please be aware that you should **NEVER** use user input like `$_POST` directly in SQL statements (even when mapped to variables)! You should use [**prepared statements**](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php) instead, binding your `$_POST` variables to parameters. Given your code above, you have a **serious** security vulnerability. You can refer to [**this post**](http://stackoverflow.com/questions/60174) for further information on how to prevent SQL injection in PHP :) – Obsidian Age Oct 30 '19 at 21:22
  • Thank you at the moment I am trying to get the basic functionality to work before I think about security. – jsmith Oct 30 '19 at 21:34
  • I am not sure which answer applies to my problem, I didn't realise it can be that many things, the code is quite short and straightforward unless I'm missing something – jsmith Oct 30 '19 at 21:35
  • Shouldn't it be `$query = "SELECT * FROM users WHERE username='$a' AND password='$b' AND isadmin=1";` – Clint Oct 30 '19 at 21:40
  • 1
    `$conn->query()` and `mysqli_query` do the same thing, they are different programming style, read about them [here](https://www.php.net/manual/en/mysqli.query.php). Note about their accept parameter and return value. – catcon Oct 30 '19 at 21:42
  • 2
    @ozeol Don't think of prepared statements as adding security, they should be part of the basic functionality. – Barmar Oct 30 '19 at 21:46
  • **Never store passwords in clear text or using MD5/SHA1!** Only store password hashes created using PHP's [`password_hash()`](https://php.net/manual/en/function.password-hash.php), which you can then verify using [`password_verify()`](https://php.net/manual/en/function.password-verify.php). Take a look at this post: [How to use password_hash](https://stackoverflow.com/q/30279321/1839439) and learn more about [bcrypt & password hashing in PHP](https://stackoverflow.com/a/6337021/1839439) – Dharman Oct 30 '19 at 22:31
  • @ObsidianAge Just in case you didn't notice, the duplicate is not correct one here. OP used `query()` method twice. In any case the duplicate you suggested is about the old `mysql_*` API not mysqli – Dharman Oct 30 '19 at 22:34

2 Answers2

0

Your main error is that you call the query() method twice. Both $conn->query and mysqli_query() are the same thing, and when you pass the result of one to the other you get this cryptic error.

Another issue is that your connection for mysqli is not up to the standards. See https://phpdelusions.net/mysqli/mysqli_connect to learn more about connecting. You should also enable error reporting with mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); instead of manually checking for errors with or die(mysqli_error($conn));

You should use parameterized prepared statements instead of manually building your queries. They are provided by PDO or by MySQLi. Never trust any kind of input! Even when your queries are executed only by trusted users, you are still in risk of corrupting your data.

Never store passwords in clear text or using MD5/SHA1! Only store password hashes created using PHP's password_hash(), which you can then verify using password_verify(). Take a look at this post: How to use password_hash and learn more about bcrypt & password hashing in PHP

I haven't fixed all of your issues, I leave that as an exercise for you, but this should act as a guide on what the proper mysqli code should look like.

<?php

session_start();

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new mysqli("localhost", "root", "", "...");
$conn->set_charset('utf8mb4');

$stmt = $conn->prepare('SELECT * FROM users WHERE username=? AND password=? AND isadmin=1');
$stmt->bind_param('ss', $_POST["username"], $_POST["password"]);
$stmt->execute();
$result = $stmt->get_result();

$firstRow = $result->fetch_assoc(); // See https://phpdelusions.net/mysqli/check_value

if ($firstRow) {
    $_SESSION["admin"] = $_POST["username"];

    exit(header("Location: index.php")); // Always `exit()` after `header('Location: ...');`
} elseif (!$result) {
    $_SESSION["gatekeeper"] = $_POST["username"];

    exit(header("Location: index.php")); // Always `exit()` after `header('Location: ...');`
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
-2

You don't need to call $conn->query when assigning the $query variable. Just assign the string. The next line executes the query.

$query = "SELECT * FROM users WHERE username='$a' AND          password='$b' AND isadmin=1";

Your code executes the query, then tries to execute the result again as if it were a query string.

Barmar
  • 741,623
  • 53
  • 500
  • 612