开发者

Question about PHP function return

The following codeigniter function takes a (string) parameter and returns the (integer) ID of the row. It works fine if i pass string values, but if integer 0 is passed, it returns ID of first row in database. In principle, it should return the user_id only if the the user_name exists in the database. Since there is no user_name called 0, it should return false. Can someone tell why it is behaving like this and how it can be fixed?

Thanks.

public function get_user_id($user_name)
    {
        $this -> db -> select('user_id');
        $this -> db -&g开发者_JS百科t; from('users');
        $this -> db -> where('user_name', $user_name);
        $this -> db -> limit(1); 

        $query = $this->db->get();

        if ( $query->num_rows > 0 )
        {
            $row = $query->row();
            return $row->user_id;
        }       
    return false;       
    }

For example:

$user_name = "test";  //works fine, returns id.
$user_name = "0";   //works fine, doesnt return anything
$user_name = 0;     //Problem. returns ID of first row.


You should add a test of the kind if ($user_name == "") return false; to catch this.

Apparently where with second argument 0 always matches, e.g. translates into SQL WHERE user_name, rather than WHERE user_name = "", and WHERE user_name is short-hand for WHERE user_name != "" -- the opposite of what you wanted :-)

Running this test at the beginning saves you a full database query when you're passed an argument that will necessarily result in false.


you can try to cast $user_name to string before pass it as a param:

$user_name = (string)$user_name;


You can use http://php.net/strval to force the variable to be a string:

$this -> db -> where('user_name', strval($user_name));

You can also try:

$this -> db -> where('user_name', "$user_name");


It's likely to be a type issue, and how the codeigniter or perhaps SQL is dealing with the integer.

Since you know username is going to be a string, cast everything to a string. I believe the following should fix any problems here;

$this -> db -> where('user_name', (string) $user_name);

If you expect objects may also be passed to this object, you'd best do a conditional:

if(is_object($user_name)) {
     $user_name = $user_name->__toString();
} else {
     $user_name = (string) $user_name;
}

Put that, of course, at the start of the function, before you select the database.


This has bugged me a few times, but so you know, some info from MySQL Documentation.

"this is known and documented feature of MySQL. When you compare numbers to strings, they are compared as float numbers. Any string that does NOT start with a digit is implicitly converted to number 0. Hence the results you get. Please, always compare numbers to numbers and strings to strings if you want to prevent undesired results."

Read http://dev.mysql.com/doc/refman/5.0/en/type-conversion.html for the details.

So, casting is the concrete way of ensuring proper comparison in the query... or from MySQL again... there is no real fix other than to make sure string literals are quoted.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜