I got this error while trying to fetch data using prepare on a select statement

if (isset($POST['submit'])){
$email = $
POST['user'];
$password = $_POST['password'];

$state = $myPDO->prepare("SELECT * FROM users WHERE email=? AND password=?");
$state->bind_param("si", $_POST['email'], $_POST['password']);

$state->execute();
$result = $state->fetchAll();
if ($result['email'] == $email && $result['password'] == $password){
    header("Location: dashboard.php");
}
$state->close();

fidelcom error "Fatal error: Uncaught Error: Call to a member function prepare() on null in C:\xampp\htdocs\app\public\index.php:9 Stack trace: #0 {main} thrown in C:\xampp\htdocs\app\public\index.php on line 9"

    Which means that you failed to give $myPDO a value.

      $myPDO is my DB connection that is included from my config.php file

        That might be what it's supposed to be, but your error message is saying that it is null.

          Once you solve why your connection doesn't exist in that variable, you have several other problems.

          1. Your connection is apparently using the PDO extension. However, the bind_param statement is from the mysqli extension and won't work with the PDO extension. For the PDO extension, simply supply an array of the input parameters to the ->execute([...]) method call.
          2. You should hash the password when it is saved, during registration, and then test if the submitted password matches the saved hashed value. See php's password_hash() and password_verify() functions.
          3. The fetchAll() method returns an array of row(s). The current logic testing elements in $result will produce php errors because $result[0]... would hold the row of fetched data, not $result. For a query that at most will match one row, just use the ->fetch() method.
          4. You must test in your code if a row of data was fetched before using any of the fetched data. Your current logic will allow empty/non-existent values to produce a true comparison and make it look like the login matched user data.
          5. When a user logs in, you must remember who the logged in user is. Store the user id (auto-increment primary index) in a session variable.
          6. If there's any logic after the code you have shown, you must add an exit; statement after the header() redirect to stop program execution.
          7. The ->close() method call is also from the mysqli extension and won't work with the PDO extension. In most cases, once you have fetched all the data from a select query, there's no need to close a prepared statement, free up a result, or close the database connection as these will all get destroyed when your script ends.
          8. You should also validate the submitted form data before using it. If either or both the email or the password is empty, there's no point in running any code trying to use those values.
          9. Be consistent in your code, don't change names of things. If a form field is an email address, don't call the value 'user' at one point and $email at another.
          10. Only SELECT the columns you want in a query. Don't use SELECT *.

          pbismad However, the bind_param statement is from the mysqli extension and won't work with the PDO extension. For the PDO extension, simply supply an array of the input parameters to the ->execute([...]) method call.

          That's how I prefer to do it, but a series of bindParam() calls is also an option (if you prefer verbosity 😉 ).

            pbismad there's no need to close a prepared statement, free up a result, or close the database connection as these will all get destroyed when your script ends.

            Earlier than that: things get cleaned up when they go out of scope (e.g. once there are no longer any live references to the connection object the object is destroyed, which includes disconnecting from the database).

              5 months later
              Write a Reply...