Достаточно ли filter_var для очистки целочисленного ввода для запросов MySQL на основе PHP? - PullRequest
1 голос
/ 22 ноября 2008

Мне никогда не нравилось упаковывать

mysql_real_escape_string 

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

filter_var 

функция. Nice!

Я сейчас использую код:

if (isset($idUserIN) 
    && filter_var($idUserIN, FILTER_VALIDATE_INT) 
    && 0 < filter_var($idUserIN, FILTER_SANITIZE_NUMBER_INT)
    ) {
      $idUser = filter_var($idUserIN, FILTER_SANITIZE_NUMBER_INT);
      $sql = 'SELECT * FROM TABLE_NAME WHERE idUser = '.$idUser;
} else {
  // handle invalid data
}

Это оставляет какие-либо открытые отверстия?

(выбрано '> 0' вместо '> = 0' в качестве поля таблицы auto_increment, поэтому 0 не будет нормальным значением)

Ответы [ 3 ]

2 голосов
/ 22 ноября 2008

Я бы сам создал функцию для этой задачи, возможно где-то в статическом классе,

public static function escape_int($i) {
    $sanitised = intval($i); 
    if( '_' . $sanitised . '_' === '_' . $i . '_'  && $sanitised > 0 ) {
        return $sanitised;
    }
    throw new IntegerEscapeException( $i, $sanitised );
    return "ENOINT"; # Wont Run This, but I prepare for the impossible. 
}

try { 
    $sql = 'SELECT * FROM TABLE_NAME WHERE idUser = ' . DB::escape_int( $userid ); 
    DB::query($sql); 
    ...etc...
} catch( IntegerEscapeException $e ) { 
    die ( "You shot the sherif!" ); # bad example.
}

Это хорошо, потому что, если я обнаружу, что мой метод санации пахнет, я могу исправить это позже.

1 голос
/ 22 ноября 2008

Я использую гораздо более простой и удобный для чтения метод:

$sql = 'SELECT * FROM TABLE_NAME WHERE idUser = ' . intval($idUser);

Он пытается преобразовать $ idUser в целое число, и при ошибке возвращает 0, которое ни одна из моих таблиц не имеет в качестве реальных идентификаторов. (Так что я знаю, что ввод был недействительным, если он оценивается как 0.)

Чтобы ответить на ваш актуальный вопрос, нет, это не оставит никаких открытых отверстий. Я предлагаю избавиться от повторяющегося кода, хотя:

$idUserIN_filtered = filter_var($idUserIN, FILTER_VALIDATE_INT);

if (isset($idUserIN) 
    && $idUserIN_filtered 
    && 0 < $idUserIN_filtered
    ) {
      $sql = 'SELECT * FROM TABLE_NAME WHERE idUser = '.$idUser_filtered;
} else {
  // handle invalid data
}
0 голосов
/ 22 ноября 2008

Это все, что вам нужно

if ($idUser = filter_var($idUserIN, FILTER_VALIDATE_INT)) {
      $sql = 'SELECT * FROM TABLE_NAME WHERE idUser = '.$idUser;
} else {
  // handle invalid data
}

или

if ($idUser = filter_input(INPUT_POST, 'userId', FILTER_VALIDATE_INT)) {

В качестве альтернативы вы можете проверить, является ли он недействительным в MVC.

if (!$idUser = filter_var($idUserIN, FILTER_VALIDATE_INT)) {
      throw new InputParameterException('UserId');
}
//else its valid
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...