简体   繁体   中英

MySQL query conjunction acting abnormally

I'm having a problem with a query. I query from one table using the following process (using php PDO and MySQL):

Build the query string $sql:

SELECT *  
FROM  `user`  
WHERE (`username`=:username OR  `email`=:username) 
      AND  `password`=:password AND  `valid`='1'; 

And using this array $params:

Params
(
    [:password] => 18155dbf12503d726883784d1d9755f8d3382ba7
    [:username] => fakeEmail@fakeEmail.com
)

Call this function:

$results_array = $database->QueryForObject($sql, $params);

public function QueryForObject($query, $binds)
{
     $stmt = $this->db->prepare($query);

     foreach($binds as $bindKey => &$key)
     {
        $stmt->bindParam($bindKey, $key, PDO::PARAM_STR);
     }

     return $this->RunObjectQuery($stmt, NULL , "stdClass");
}

My problem is that the username can be incomplete or even missing, and all it uses to find the user is the password... I'm pretty sure it shouldn't do that, but I can't figure out why.

As a side note, here is the description of my table:

Field            , Type                                           , Null  ,Key  ,Default , Extra
id               , int(10) unsigned                               , NO    ,PRI  ,NULL     auto_increment 
username         , varchar(30)                                    , NO    ,UNI  ,NULL                    
email            , varchar(50)                                    , NO    ,     ,NULL                    
password         , varchar(100)                                   , NO    ,     ,NULL                    
first_name       , varchar(30)                                    , NO    ,     ,NULL                    
last_name        , varchar(30)                                    , NO    ,     ,NULL                    
rights           , enum('normal','medium','high','admin','super') , NO    ,     ,NULL                    
last_loggedin    , timestamp                                      , YES   ,     ,NULL                    
status           , enum('current','expired','temporary')          , NO    ,     ,NULL                    
valid            , tinyint(1)                                     , NO    ,     ,NULL                    
other_comments   , varchar(500)                                   , YES   ,     ,NULL                    
gender           , enum('male','female')                          , YES   ,     ,NULL                    
company_position , varchar(50)                                   ,  YES  ,     , NULL   

Any suggestions are welcomed!!

This isn't a definitive answer, but I believe I recall a bug with PDO and named bind parameters, with the same named bind parameter appearing more than once. (When we looked into it, it looked as the named arguments were being translated into positional arguments, and the bind_param was only setting one of the arguments.

As a workaround, we ensured that the named parameter appeared only once in the statement.

In your case, you might try (as a test) modifying the SQL so that it has only two named bind parameters, eg

SELECT *  
  FROM  `user`  
 WHERE :username IN (`username`,`email`)
   AND  `password`=:password AND `valid`='1'; 

Another alternative is to create a third named argument, and provide a separate bind value for the third parameter.

This isn't a definitive answer, just a suggestion of an approach that may allow you to debug this issue.

(In our case, we went with the workaround, each named argument in the SQL statement was unique, and we provided a separate bind for each parameter.)

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