phpmysqlpdoexecuteprepare

Warning: PDO::prepare() expects parameter 1 to be string, object given


I have been trying to convert a old mysql too pdo as I am trying to learn how pdo works, I have been working on this one file for hours now busting my head and can not figure out what is wrong, and I'm sure its a lot.

try{
    $check_user_data = $dbh->query("SELECT * FROM members WHERE username = '$username'");
    $stmt = $dbh->prepare($check_user_data);
    $stmt->execute();
    $result->bind_result($username);
    $data_exists = ($check_user_data->fetchColumn() > 0) ? true : false;
    if($data_exists = false){
        $final_report.="This username does not exist..";
    }else{
        $get_user_data = $stmt->fetch(PDO::FETCH_ASSOC);
        if($get_user_data['password'] == $password){
            $start_idsess = $_SESSION['username'] = "".$get_user_data['username']."";
            $start_passsess = $_SESSION['password'] = "".$get_user_data['password']."";
            $final_report.="You are about to be logged in, please wait a few moments.. <meta http-equiv='Refresh' content='2; URL=members.php'/>";
        }
    }
    foreach ($dbh->query($sql) as $row){
    }
    $dbh = null;
}
catch(PDOException $e){
    echo $e->getMessage();
}

Also getting a fatal

Fatal error: Call to a member function execute() on a non-object

Not sure if the fatal is related to the warning or not.


Solution

  • First, change these two lines:

    $check_user_data = $dbh->query("SELECT * FROM members WHERE username = '$username'");
    $stmt = $dbh->prepare($check_user_data);
    

    to:

    $stmt = $dbh->prepare("SELECT * FROM members WHERE username = :username");
    $stmt->bindParam(':username', $username);
    

    This makes use of the parameter feature of prepared statements, which prevents SQL injection.

    Next, PDO doesn't have a bind_result method, that's part of MySQLI. To get the results, you should do:

    $get_user_data = $stmt->fetch(PDO::FETCH_ASSOC);
    $data_exists = ($get_user_data !== false);
    

    You should then remove the call to $stmt->fetch in the else block, because it will try to get the next row of results.