MYSQL-запрос волшебным образом захватывает числовые значения - PullRequest
1 голос
/ 17 июля 2011

У меня следующий запрос

SELECT * FROM (`user_profiles`) WHERE `user_id` = $user_id LIMIT 1

$user_id - это сегмент URI.Например, $user_id = 64 выдаст

SELECT * FROM (`user_profiles`) WHERE `user_id` = '64' LIMIT 1

Если я добавлю алфавитные символы к идентификатору пользователя, например, http://www.mysite.com/profile/64kjdsg

, я получу:

SELECT * FROM (`user_profiles`) WHERE `user_id` = '64kjdsg' LIMIT 1

, который все ещевозвращает правильные данные, хотя нет идентификатора пользователя, равного 64kjdsg.Столбец идентификатора пользователя в моей таблице int (11).Похоже, что запрос автоматически получает числовое значение из 64kjdsg и соответствует этому значению в таблице базы данных.Это функция MYSQL, о которой я не знаю?

Как это происходит?Я запрашиваю использование платформы Codeigniter, если это имеет значение для муравья.

ОБНОВЛЕНИЕ: найден похожий вопрос Сравнение целых чисел MySQL игнорирует конечные буквенные символы

Ответы [ 4 ]

2 голосов
/ 17 июля 2011

Когда вы сравниваете числовой столбец, MySQL преобразует вашу строку в число (поэтому он удаляет все из появления первого нецифрового символа).Это его поведение по умолчанию :

mysql> select '23andthensome' + 4;
+---------------------+
| '23andthensome' + 4 |
+---------------------+
|                  27 |
+---------------------+
1 row in set, 1 warning (0.02 sec)

mysql> show warnings;
+---------+------+---------------------------------------------------+
| Level   | Code | Message                                           |
+---------+------+---------------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '23andthensome' |
+---------+------+---------------------------------------------------+
1 row in set (0.02 sec

Итак, сделайте более правильные запросы, предварительно проверьте, является ли число числом (filter_var(FILTER_VALIDATE_INT,$id);), используйте его только тогда, когда оно есть, а затем:не отправляйте его как строку в MySQL: если вы хотите сравнить числа, отправьте число, которое не должно быть заключено в кавычки.

В качестве альтернативы, вы можете позволить MySQL выполнять работу, но это кажется пустой тратой:

mysql> select 23 = '23andthensome';
+----------------------+
| 23 = '23andthensome' |
+----------------------+
|                    1 |
+----------------------+
1 row in set, 1 warning (0.00 sec)
mysql> select cast(23  as CHAR) = '23andthensome';
+-------------------------------------+
| cast(23  as CHAR) = '23andthensome' |
+-------------------------------------+
|                                   0 |
+-------------------------------------+
1 row in set (0.02 sec)
1 голос
/ 17 июля 2011

Проверьте это: http://ideone.com/khpEv, это называется жонглированием типа. Если вы '64kjdsg' строка будет преобразована в целое число (64), потому что user_id это INT, иначе это приведет к синтаксической ошибке.

Пример PHP:

<?php
echo (int) '64kjdsg'; // 64
?>
1 голос
/ 17 июля 2011

Проверьте в вашем скрипте целое число urlsegment.Вы можете использовать ctype_digit, чтобы сделать это.Если нет, не трогай свою БД.Скажите "Нет такого пользователя"

0 голосов
/ 17 июля 2011

это дыра в безопасности однако, если

$user_id = 5;

результат

SELECT * FROM (`user_profiles`) WHERE `user_id` = 5 LIMIT 1

не

SELECT * FROM (`user_profiles`) WHERE `user_id` = `5` LIMIT 1

попробуйте использовать intval()

$user_id = intval($user_id);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...