Оператор PHP If для проверки, пусты ли поля формы

Я пытаюсь проверить 2 вещи

  1. То, что форма, используемая для вызова скрипта для вставки записи в базу данных, была выполнена реальным пользователем, нажимающим кнопку отправки, в отличие от угрозы бота или SQL-инъекции.

  2. Чтобы убедиться, что все поля содержат данные, чтобы предотвратить ввод строки с пустыми данными.

Заявление, которое у меня есть сейчас:

if (!$_POST['submit']) {    
   die('Error: ' . mysqli_error());
   echo "Please complete all form fields!";
   echo "<meta http-equiv='Refresh' content='3; URL=../add.php'>";
}

Этот оператор if должен делать и то, и другое, но я не уверен, что это лучший способ сделать это, и я не вижу, что он проверяет/предотвращает пустые поля. В форме есть кнопка отправки с name="submit".

Любые мысли или предложения приветствуются.


person user3146788    schedule 04.01.2014    source источник
comment
Измените if (!$_POST['submit']) { на if (!isset($_POST['submit'])){, это самый простой способ.   -  person Funk Forty Niner    schedule 04.01.2014


Ответы (6)


Вы должны сделать это следующим образом:

if(isset($_POST['submit'])) {
    foreach($_POST as $val) {
        if(trim($val) == '' || empty($val)) {
            //empty field, do something
            ...
            header("Location: /add.php?error=empty_fields");
            die();
        }
    }
    //all seems to be ok
    ...
}

Чтобы предотвратить внедрение SQL, используйте PDO, и вы забудете об этом.

person Dmitry Astrikov    schedule 04.01.2014
comment
Мне очень нравится этот подход, однако мне нужно было бы сделать header("Location: ../add.php?error=empty_fields"); остановку или подождать 3-5 секунд, чтобы я мог отобразить сообщение, такое как: echo "Please complete all form fields!"; Я использовал это: echo "<meta http-equiv='Refresh' content='3; URL=../add.php'>"; поскольку это позволяет мне сделать задержку, это плохой подход по сравнению с использованием header()? - person user3146788; 04.01.2014

Одним из методов обнаружения ботов является использование поля-приманки, такого как это

<input type="text" name="check" value="" style="display:none;" />

а затем обнаружить бота

if (!empty($_POST['check'])) { /* bot detected! */ }

Причина, по которой это работает достаточно хорошо, заключается в том, что боты тупые. Они попытаются заполнить все необходимые поля, которые могут иметь отношение к успешной отправке, чтобы избежать проблем с обязательными полями. Важно отметить, что вместо type="hidden" использовалось type="text", потому что большинство ботов знали бы, что скрытые поля не являются частью обязательной проверки полей.

Проверка на $_POST['submit'] часто не работает, потому что многие боты будут эмулировать веб-страницу.

person sjagr    schedule 04.01.2014
comment
Отвечает только на один вопрос ОП, но это умно. - person AKS; 04.01.2014
comment
@AyeshK Спасибо! Существует много информации/методов проверки, позволяющих OP сделать это самостоятельно, и он не опубликовал адекватного кода, кроме своей попытки проверить $_POST['submit']. Казалось, его больше беспокоит обнаружение ботов, поэтому я сосредоточился на этой части. - person sjagr; 04.01.2014
comment
может быть, потому что уже слишком поздно или я тупой, но я не могу понять, почему бот должен быть пойман на этом. Думая о том, как бы я написал оба, я бы сделал так, чтобы он отправлял check=, т.е. пустое значение, для поля, которое он не знает, как заполнить, чтобы сделать его значимым. Но, конечно, есть бот для разных целей, так что это тоже должно зависеть от этого. - person ShinTakezou; 04.01.2014
comment
@ShinTakezou Это не верный способ, но общая концепция заключается в том, что сканирующий спам-бот не может утруждаться выбором необязательных полей из обязательных, поэтому он просто заполняет их все. Да, вы можете анализировать контекст полей input, чтобы поместить определенные данные в каждое, но атрибут name поля input может быть контекстуально неуместным (поскольку это часть разметки, а не для конечного пользователя). about — это textarea, который обычно используется для сообщения, сообщения в блоге и т. д. - person sjagr; 04.01.2014

Вы должны проверить каждое поле одно за другим, чтобы убедиться, что все поля были заполнены. Запись $_POST['submit'] существует, если вы фактически нажмете кнопку отправки.

if (!$_POST['name'] || empty($_POST['name'])
    || !$_POST['email'] || empty($_POST['email'])
    || ...) {    
    echo "Please complete all form fields!";
    echo "<meta http-equiv='Refresh' content='3; URL=../add.php'>";
}

Существует множество методов рефакторинга и улучшения написания такого рода проверки. Пример, от W3Schools:

<?php
// define variables and set to empty values
$name = $email = $gender = $comment = $website = "";

if ($_SERVER["REQUEST_METHOD"] == "POST")
{
  // Sanitize every var from SQL injection, XSS and strip spaces...
  $name = test_input($_POST["name"]);
  $email = test_input($_POST["email"]);
  $website = test_input($_POST["website"]);
  $comment = test_input($_POST["comment"]);
  $gender = test_input($_POST["gender"]);

 if(empty($name) || empty($email) || empty($website) || empty($comment) || empty($gender)) {
    echo "Please complete all form fields!";
    echo "<meta http-equiv='Refresh' content='3; URL=../add.php'>";
 }
}


function test_input($data)
{
  $data = trim($data);
  $data = htmlspecialchars(addslashes($data));
  return $data;
}
?>
person Maxime Lorant    schedule 04.01.2014
comment
хорошо, это имеет смысл для проверки полей, что вы думаете о проверке статуса отправки, рекомендуется ли это для безопасности? - person user3146788; 04.01.2014
comment
Если ожидаемые данные отправлены, я думаю, вам не нужно проверять кнопку отправки. Избежать проверки формы извне может быть очень дешевой защитой, но этим должно управляться с помощью токена csrf: en.wikipedia.org/wiki/Cross-site_request_forgery (но я не хочу вас сейчас беспокоить, возможно, уровень слишком высок для вас на данный момент :) ) - person Maxime Lorant; 04.01.2014

  1. Вы не можете быть уверены, что это не бот. И вы можете избежать SQL-инъекций с помощью хороших простых методов кодирования, но ваш фрагмент кода слишком мал, чтобы показать что-либо из этого, используете ли вы их или нет.
  2. Также добавьте проверку на стороне клиента (используя Javascript); если вы получаете пустые значения, то, скорее всего, форма была отправлена ​​​​не через обычный браузер, но могут быть и другие причины, например. Javascript отключен, так что вы не можете быть уверены.

Вы также можете проверить User-Agent, но помните, что его можно подделать. И этот бот также может добавить правильное поле Submit!

person ShinTakezou    schedule 04.01.2014

Шаг 1. Проверка на стороне клиента

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

Это поможет гарантировать, что если пользователь отправит форму, он будет вынужден заполнить все поля формы, прежде чем данные будут отправлены на сервер.

Шаг 2. Проверка на стороне сервера

Если вы пытаетесь выполнить полную проверку значений формы в форме, я бы сделал что-то вроде этого:

 $form_fields = array('email','fname','lname');
 $isValid = true;
 foreach($_POST as $key=>$value){
      if(in_array($key,$form_fields)){
           if(empty($value) { 
                $isValid = false;
           }
      }
 }
 if(!isValid) {
      header("Location: /add.php?error=1");
      die();
 }

При таком подходе вы определяете все имена полей, которые вам нужны, в верхней части скрипта и просто просматриваете объект $_POST, чтобы увидеть, есть ли назначенные данные/значение. Это, конечно, не принимает во внимание какую-либо проверку типа поступающих данных, и я бы рекомендовал подумать об этом, чтобы вы не получали неверные данные. Если вам нужно проверить правильно отформатированные данные, вам придется проверять каждый ввод формы отдельно.

Шаг 3. Подготовленные операторы SQL

Последней рекомендацией для защиты от SQL-инъекций будет использование подготовленных операторов SQL. при вставке данных в базу данных. Или рассмотреть ORM, который сделает это за вас. Для этого я бы рекомендовал:

Необязательный шаг: одноразовый номер PHP

Если вы беспокоитесь о том, что кто-то отправит СПАМ через страницу, которая обрабатывает вашу форму, вы можете реализовать одноразовый номер. Этот криптографический ключ гарантирует, что форма может быть отправлена ​​только один раз, а любые другие отправки будут отклонены. Опять же, я не уверен, насколько безопасно вы хотите быть в своем проекте, но это тоже следует учитывать.

Это довольно хорошая библиотека для одноразовых номеров в PHP:

person Liam    schedule 04.01.2014

Это полный скрипт, извините, я не разместил в исходном посте:

<?php
//Form fields passed to variables
$manu = mysql_real_escape_string($_POST['inputManu']);
$model = mysql_real_escape_string($_POST['inputModel']);
$desc = mysql_real_escape_string($_POST['inputDesc']);

//Connect to database using $conn
include ('connection.php');

$sql = "INSERT INTO gear (`id`,`manu`,`model`,`desc`)
    VALUES (NULL,'$manu','$model','$desc')";

//Check for empty fields
if (!$_POST['submit']) 
{   
   die('Error: ' . mysqli_error());
   echo "Please complete all form fields!";
   echo "<meta http-equiv='Refresh' content='3; URL=../add.php'>";
}
//Insert record into table 
elseif (!mysqli_query($conn,$sql))
{
die('Error: ' . mysqli_error($conn));
}
else 
{
//echo "1 record added";
echo "Success, You added the ".$manu." ".$model."";
echo "<meta http-equiv='Refresh' content='3; URL=../index.php'>";
}           
mysqli_close($conn);
?>
person user3146788    schedule 04.01.2014
comment
Очевидно, что это добавляет пустые записи, и я намерен протестировать предложенные здесь варианты, предполагая, что вы по-прежнему рекомендуете те же подходы после просмотра полного кода. - person user3146788; 04.01.2014