Поймать бланк (включая все пробелы) формы представления - PullRequest
1 голос
/ 01 февраля 2009

Если на моем сайте есть проблема, пользователи могут публиковать пустые сообщения, если используют пространство.

Код:

if (isset($_POST['submit'])) {

  // check for empty fields
  if (empty($_POST['headline']) || empty($_POST['text']) ||
      empty($_POST['forum_id'])) {
      header("Refresh: 2; url=/add-thread"); 
      die('You must fill out every field.');
  }

// No errors? Save.
else {
$headline = mysql_real_escape_string($_POST['headline']);
$text = mysql_real_escape_string($_POST['text']);

mysql_query("INSERT INTO threads (headline, text, date, forum_id, user_id)
             VALUES ('$headline', '$text', NOW(), '$_POST[forum_id]', '$user[id]')");

header("Location: /thread/".mysql_insert_id()."");
}

}

Как я могу это исправить?

Ответы [ 7 ]

9 голосов
/ 01 февраля 2009

trim() текстовые входы. Вы можете сделать это легко, как это:

// get input vars and trim space
$callback = array('filter' => FILTER_CALLBACK, 'options' => 'trim');
$fields = filter_input_array(INPUT_POST, array(
    'headline' => $callback,
    'text'     => $callback,
    'forum_id' => $callback,
));

// check for empty fields by counting how many are set
if ( count($fields) != count(array_filter($fields)) ) {
    // something was unset
}
3 голосов
/ 01 февраля 2009

Пустая функция проверяет переменные, которые удовлетворяют установленным критериям, начиная с руководство

Возвращает FALSE, если переменная имеет непустое и ненулевое значение.

Следующие вещи считаются пустыми:

  • "" (пустая строка)

  • 0 (0 в виде целого числа)

  • "0" (0 в виде строки)

  • NULL

  • FALSE

  • array () (пустой массив)

  • var $ var; (объявленная переменная, но без значения в классе)

Ваши поля $ _POST фактически содержат что-то вроде этого

"   "; 

Это не пустая строка, а строка, заполненная пробельными символами.

Перед использованием empty () обрежьте () пробел из ваших значений POSTed

$trimmed_post = array();
foreach($_POST as $key=>$value){
    $trimmed_post[$key] = $value;
}
if(!empty($trimmed_post['headline'])){
    //...
}

Вам не нужно помещать новые значения в новый массив, но я не большой поклонник изменения того, что находится в автоматически генерируемых суперглобалах.

Последнее замечание, вы не можете сделать что-то подобное

if(!empty(trim($_POST['headline']))){
   //...
}

потому что пустая функция ожидает передачи фактической переменной. Вы могли бы сделать что-то вроде этого вместо

if('' != trim($_POST['headline'])){
//...
}

Возможно, это лучший подход. Вы уменьшаете количество функций, которые вам нужно вызывать, пользователи могут публиковать записи со значением 0, и код более четко описывает, что он делает. Еще одна форма, которую вы увидите

if(trim($_POST['headline'])){

}

Это работает, потому что PHP оценивает пустую строку ('') как false, а непустую строку как true. Я склонен избегать этой формы, потому что я обнаружил множество ошибок PHP, возникающих из-за недопонимания того, как операторы равенства получают логические значения из определенных типов. Быть явным помогает уменьшить количество ошибок такого типа.

1 голос
/ 01 февраля 2009

Я согласен, что обрезка это путь. Вот гораздо более простой способ сделать это:

$_POST = array_map('trim', $_POST);
1 голос
/ 01 февраля 2009

Просто краткое замечание: вы вводите значение $_POST['forum_id'] в SQL; это не очень хорошая идея, поскольку пользователь может манипулировать этим значением по своему желанию, даже если оно исходит из скрытого поля. Было бы разумно избежать значения или, по крайней мере, пропустить его через intval() и убедиться, что оно является целым числом (при условии использования интегральных идентификаторов записей).

0 голосов
/ 01 февраля 2009

Я обрезаю каждую переменную $_GET & $_POST сразу после запуска приложения. попробуйте что-то вроде этого:

function trimArray(&$array) {
    if (empty($array)) {
        return;
    }

    foreach ($array as $k => $v) {
        if (! is_array($v)) {
            $array[$k] = trim($v);
        } else {
            trimArray($v);
        }
    }
}

if (! empty($_GET)) {
    trimArray($_GET);
}
if (! empty($_POST)) {
    trimArray($_POST);
}
0 голосов
/ 01 февраля 2009

Сразу после проверки заявки:

foreach ( $_POST as $key => &$value ) $value = trim($value);

изменить в ответ на комментарий автора:

Странно, что это не сработало, как указано выше. Вот мое упражнение, чтобы подтвердить это.

tbramble@wayfarer:~$ php -a
Interactive shell

php > $arr = array('one',' two', ' three ');
php > print_r($arr);
Array
(
    [0] => one
    [1] =>  two
    [2] =>  three 
)
php > foreach ( $arr as $key => &$value ) $value = trim($value);
php > print_r($arr);
Array
(
    [0] => one
    [1] => two
    [2] => three
)    

Должен иметь отношение к работе над суперглобальным вместо обычного массива.

0 голосов
/ 01 февраля 2009

Попробуйте

if (!empty($_POST['headline']) && !empty($_POST['text']) &&
!empty($_POST['forum_id']))

Для логики.

Тебе все равно придется переключить.

ОБНОВЛЕНИЕ, чтобы уточнить:

if (isset($_POST['submit']) && !empty($_POST['headline']) && 
!empty($_POST['text']) && !empty($_POST['forum_id'])) {

    $headline = mysql_real_escape_string($_POST['headline']);
    $text = mysql_real_escape_string($_POST['text']);

    mysql_query("INSERT INTO threads (headline, text, date, forum_id, user_id)
         VALUES ('$headline', '$text', NOW(), '$_POST[forum_id]', '$user[id]')");

    header("Location: /thread/".mysql_insert_id()."");
}
else
{
  header("Refresh: 2; url=/add-thread"); 
  die('You must fill out every field.');    
}

}

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