Вопрос о возврате функции PHP - PullRequest
2 голосов
/ 22 июня 2011

Следующая функция codeigniter принимает (строковый) параметр и возвращает (целочисленный) идентификатор строки.Он работает нормально, если я передаю строковые значения, но если передано целое число 0, он возвращает идентификатор первой строки в базе данных.В принципе, он должен возвращать user_id, только если в базе данных существует user_name.Поскольку нет имени пользователя с именем 0, оно должно вернуть false.Может кто-нибудь сказать, почему он так себя ведет и как это можно исправить?

Спасибо.

public function get_user_id($user_name)
    {
        $this -> db -> select('user_id');
        $this -> db -> 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;       
    }

Например:

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

Ответы [ 5 ]

2 голосов
/ 22 июня 2011

Вы должны добавить тест вида if ($user_name == "") return false;, чтобы поймать это.

Очевидно, where со вторым аргументом 0 всегда совпадает, например, переводит в SQL WHERE user_name, а не WHERE user_name = "", иWHERE user_name - это сокращение от WHERE user_name != "" - противоположность того, что вы хотели: -)

Запуск этого теста в начале спасет вас от полного запроса к базе данных, когда вы передадите аргумент, который обязательно будетрезультат в false.

1 голос
/ 22 июня 2011

вы можете попробовать преобразовать $ user_name в строку перед передачей в качестве параметра:

$user_name = (string)$user_name;
0 голосов
/ 22 июня 2011

Это несколько раз меня раздражало, но, как вы знаете, некоторая информация из документации MySQL.

"это известная и задокументированная особенность MySQL. Когда вы сравниваете числа со строками, они сравниваются как floatчисла. Любая строка, которая НЕ начинается с цифры, неявно преобразуется в число 0. Отсюда и результаты, которые вы получаете. Пожалуйста, всегда сравнивайте числа с числами, а строки со строками, если вы хотите предотвратить нежелательные результаты. "

Подробнее читайте http://dev.mysql.com/doc/refman/5.0/en/type-conversion.html.

Таким образом, приведение - это конкретный способ обеспечения правильного сравнения в запросе ... или из MySQL снова ... нет другого решения, кроме как сделатьверные строковые литералы заключены в кавычки.

0 голосов
/ 22 июня 2011

Вероятно, это проблема типа и того, как codeigniter или, возможно, SQL имеет дело с целым числом.

Поскольку вы знаете, что имя пользователя будет строкой, приведите все к строке. Я считаю, что следующее должно исправить все проблемы здесь:

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

Если вы ожидаете, что объекты также могут быть переданы этому объекту, лучше всего выполнить условие:

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

Поместите это, конечно, в начале функции, прежде чем выбрать базу данных.

0 голосов
/ 22 июня 2011

Вы можете использовать http://php.net/strval, чтобы переменная была строкой:

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

Вы также можете попробовать:

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