简体   繁体   中英

Dynamic PDO parameter binding issue with WHERE clause

I have a search form where users can enter a few pieces of information to search for records in the database. Due to the fact that some of the fields can be left blank, I am dynamically creating the WHERE clause of the query as well as dynamically binding the PDO parameters. Everything works great if the user only fills out 1 field in the search form but if more than 1 field is used then an empty array is returned. Here is my code.

if(count($_POST)>0)
{   
    //Remove any key that has no value  
    $data = array_filter($_POST);

    //Define array to hold the pieces of the where clause
    $where = array();

    //loop each of the variable to build the query
    foreach($data as $key=>$value)
    {
        $key = mysql_real_escape_string($key);

        //Push values to array
        array_push($where, "$key=:$key");
    }

    //Create the select query
        $query = "SELECT application_ID, 
                     student_last_name, 
                     student_first_name,
                     s.school_name,
                     DATE_FORMAT(submission_datetime, '%m/%d/%Y %h:%i:%s %p') AS  submission_datetime, 
                     aps.name  
                     FROM application a
                     LEFT JOIN application_status aps ON(aps.status_ID = a.application_status_ID)
                     LEFT JOIN schools s ON(s.school_ID = a.school_choice)";
    //As long as criteria was selected in the search form then add the where clause to the query with user's search criteria
    if(!empty($where))
    {       
        $query .= "WHERE ".implode(" AND ", $where);
    }

    //Add ORDER BY clause to the query
    $query .= " ORDER BY application_ID";

    $stmt = $conn->prepare($query);
    //loop each of the variables to bind parameters
    foreach($data as $key=>$value)
        {
            $value = mysql_real_escape_string($value);
            $stmt->bindparam(':'.$key, $value);
        }
    $stmt->execute();
    $result = $stmt->fetchall(PDO::FETCH_ASSOC);


}

When I echo the query everything looks fine and even returns results when run from PHPMyAdmin. Here is the query.

SELECT application_ID, 
       student_last_name, 
       student_first_name, 
       s.school_name, 
       DATE_FORMAT(submission_datetime, '%m/%d/%Y %h:%i:%s %p') AS submission_datetime,
       aps.name 
       FROM application a 
       LEFT JOIN application_status aps ON(aps.status_ID = a.application_status_ID)
       LEFT JOIN schools s ON(s.school_ID = a.school_choice)
       WHERE school_choice=:school_choice AND status_ID=:status_ID 
       ORDER BY application_ID ASC

When I print_r I get an empty array. Thanks for any help you can provide.

When you iterate through an array to bind values to the PDO statement you should use bindValue instead of bindParam.

When you say $stmt->bindparam(':'.$key, $value) , the query will use the value of the variable $value as it is at the time of the query execution. Value of $value will be the last element of the array.

http://php.net/manual/en/pdostatement.bindvalue.php

I hope this helps.

You are not supposed to use mysql_real_escape_string() with prepared statements. And in fact, this function will not work if you don't have a mysql_connect() initialized, which you don't.

That must be why it all is failing, your calls to mysql_real_escape_string() are returning FALSE for everything.

Also, what makes you think array keys coming from $_POST are safe to be used in your SQL query? You are taking a serious risk of SQL injection here, don't ever do that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM