简体   繁体   中英

Database query returning incorrect row

I'm working on some web code which uses codeigniter and the built in querybuilder to access a database.

I attempt to load data from the database for the current user

$userModel = $this->loadModel('ModelUser');
$name = $this->session->userdata('user');
$user = $userModel->getUser($name);

This is the code for getUser :

function getUser($username)
{
    $this->db->where('username',$username);
    $query = $this->db->get('tblusers',1);
    $res = $query->result();
    if ($query->num_rows() > 0)
    {
        log_message('debug','Got user. ID = '.$res[0]->id);
        foreach($res[0] as $key => $val)
        {
            $this->$key = $val;
        }
        return $this;
    }
    else {
        log_message('info','failed to find user '.$username);
        return NULL;
    }
}

This works fine except when I let the session expire, in which case I get the details of another user.

These are the results of testing getUser :

$userModel->getUser("Admin"); //Got user. ID = Admin_ID
$userModel->getUser("john");  //Got user. ID = John_ID
$userModel->getUser("");      //Failed to find user
$userModel->getUser(null);    //Failed to find user

When I log in as Admin then let the session timeout, the top snippet logs the message:

Got user. ID = John_ID

I would expect either Got user. ID = Admin_ID Got user. ID = Admin_ID or Failed to find user

When $this->session->userdata('field') does not find an entry, it returns 0 instead of the "" or null that I was testing against.

Logging $this->db->last_query() showed this since the resulting query was:

SELECT * FROM tblusers WHERE username = 0 LIMIT 1;

MySQL will automatically convert strings to integers where the string starts with an integer. A string without an integer will be cast to 0 as explained in this answer . The query was returning the first entry it came across instead of finding no rows as any string that didn't start with 1-9 would match the WHERE clause.

I added a clause to getUser to return NULL if $username == '' . I did try === 0 but that yielded the same error so there's some type coercion going on that I'm not 100% certain of, but this covers the issue nicer than handling the case each time getUser is called.

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