Одним из основных способов взаимодействия пользователя с сайтом, это отправка данных в веб-форму. PHP один из самых удобных языков для обработки запросов от веб-форм, в нём на самом низком уровне реализовано всё что нужно для комфортной работы с формами. Вам не нужно разбираться с особенностями протокола HTTP, способами выполнения GET или POST запросов и т.д. разработчики языка php уже обо всём позаботились. И так поехали!

Передача данных в адресной строке

Одним из простых способов передачи данных php сценарию является адресная строка браузера, где после знака ? вы можете указать набор параметров в формате имя_параметра=значение если параметров несколько они разделяются сиvволом . Например:


http://mysite.local/script.php?username=Иван&age=25&position=менеджер

В данном примере:
  • http://mysite.local/script.php — адрес сценария
  • username=Иван — первый параметр username со значением Иван
  • age=25 — второй параметр
  • position=менеджер — третий параметра
  • & — символ разделения параметров в адресной строке

Все переданные параметры можно получить в сценарии script.php следующим образом:


/* Выведем глобальный массив $_GET в который 
попадут значения переданные через адресную строку*/

echo '<pre>';
print_r($_GET);
echo '</pre>';

Здесь мы выводим на экран глобальный массив $_GET функцией print_r() , если вы всё сделали правильно, то в браузере вы увидите примерно такой результат:

Array
(
    [username] =&gt; Иван
    [age] =&gt; 25
    [position] =&gt; менеджер
)

Справка: $_GET — это ассоциативный массив переменных, переданных php сценарию через адресную строку браузера (параметры URL). Обратите внимание, что данный массив не только заполняется для GET-запросов (отправляемых формой), а скорее для всех запросов со строкой запроса (обращения поисковых роботов, запросы к API и т.п.). Аналогично есть глобальный массив $_POST в который попадают переменные отправленные методом POST и массив $_REQUEST в который попадают все переменные из POST и GET запросов.
Такой способ передачи данных скрипту используется редко, обычно для тестирования (чтобы не писать html-форму) или когда вы пишите какой-то простой скрипт для промежуточной задаче и нужен некий «механизм» его запуска, можно поставить условие в сценарии на наличие параметра start=yes в адресной строке.

Трансляция формы

Теперь перейдём непосредственно к теме статьи. Для продолжения нам придётся сверстать небольшую форму, я предлагаю сделать её внутри тестового скрипта script.php из примеров выше. Вот пример html-формы:


<form action="/script.php" method="get">
    <label for="username">
         Имя пользователя<br/>
        <input type="text" name="username" id="username">
    </label><br/>
    <label for="age">
        Возраст<br/>
        <input type="number" name="age" id="age">
    </label><br/>
    <label for="position">
        Должность<br/>
        <input type="text" name="position" id="position">
    </label><br/>
    <label for="comment">
        Комментарий<br/>
        <textarea name="comment" id="comment" cols="30" rows="5"></textarea>
    </label><br/><br/>
    <input type="submit" name="" value="Отправить">
</form>

Обратите внимание на атрибуты формы:

  • action — адрес скрипта который будет обрабатывать запрос от формы и
  • method — метод передачи данных

Параметр method по умолчанию равен get, но я привык указывать его явно. Так же обратите внимание на то, что у каждого поля формы ОБЯЗАТЕЛЬНО должен быть атрибут name именно значение из атрибута name попадёт в адресную строку как имя_параметра.  Если вы не укажете name у полей формы, вы не сможете корректно обработать переданные скрипту данные. Давайте отправим тестовые данные через форму и посмотрим результат.

Отправка GET-запроса через форму

Адресная строка при этом содержит всё что мы вводили в поля формы:


/script.php?username=Иван&age=25&position=менеджер&comment=тестовый+комментарий

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


if(!empty($_GET['age'])){ //Проверяем что возраст заполнен
    if($_GET['age'] < 18){
        echo 'Вы слишком молоды и не можете оставить комментарий на сайте';
    } else {

        /**
         * здесь обработка полей формы, запись в БД данных и т.п.
         */

        echo 'Спасибо, ваш комментарий появится сразу после модерации';
    }
}

Пример максимально упрощён.

Обработка списков

Работа с выпадающим списком selectbox мало чем отличается от обычных полей, тут больше отличие со стороны HTML, давайте добавим в нашу форму небольшой selexbox для наглядной демонстрации:


<form action="/script.php" method="get">
    <label for="username">
         Имя пользователя<br/>
        <input type="text" name="username" id="username">
    </label><br/>
    <label for="age">
        Возраст<br/>
        <input type="number" name="age" id="age">
    </label><br/>
    <label for="position">
        Должность<br/>
        <input type="text" name="position" id="position">
    </label><br/>
    <label for="edu">
        Образование<br/>
        <select name="edu" id="edu">
            <option value="Среднее">Среднее</option>
            <option value="Средне-специальное">Средне-специальное</option>
            <option value="Высшее">Высшее</option>
            <option value="Второе высшее">Второе высшее</option>
        </select>
    </label><br/>
    <label for="comment">
        Комментарий<br/>
        <textarea name="comment" id="comment" cols="30" rows="5"></textarea>
    </label><br/><br/>
    <input type="submit" name="" value="Отправить">
</form>

Обратите внимание что у поля selectbox атрибут name указывается непосредственно в теге <select> а вот value — значение поля указывается внутри у тегов <option>. Более того, по умолчанию при выводе формы в браузере, в поле selectbox всегда выбрано первое доступное значение. Т.е. при передаче данных скрипту, в параметре $_GET[‘gov’] всегда будет выбрано «Среднее». Чтобы этого избежать, обычно добавляют дополнительный <option> в начало с пустым атрибутом value. Тогда пользователю нужно будет непосредственно выбрать доступную в выпадающем списке опцию. Так же это позволяет легко отфильтровать переданные пустые значения на стороне сервера (в php скрипте). После корректировки наше поле «Образование» приобретает такой вид:


    <label for="edu">
        Образование<br/>
        <select name="edu" id="edu">
            <option value="">Укажите образование</option>
            <option value="Среднее">Среднее</option>
            <option value="Средне-специальное">Средне-специальное</option>
            <option value="Высшее">Высшее</option>
            <option value="Второе высшее">Второе высшее</option>
        </select>
    </label><br/>

Обработка массивов

Что делать когда нужно передать несколько значений одного параметра? Например то же образование у человека может быть и средне-специальное и высшее. Можно добавить атрибут multipli в наш selectbox или использовать поле типа checkbox.  Давайте превратим наш selextbox в checkbox.


<form action="/script.php" method="get">
    <label for="username">
         Имя пользователя<br/>
        <input type="text" name="username" id="username">
    </label><br/>
    <label for="age">
        Возраст<br/>
        <input type="number" name="age" id="age">
    </label><br/>
    <label for="position">
        Должность<br/>
        <input type="text" name="position" id="position">
    </label><br/>
        Образование<br/>
        <input type="checkbox" name="edu[]" value="Среднее">Среднее <br/>
        <input type="checkbox" name="edu[]" value="Средне-специальное">Средне-специальное <br/>
        <input type="checkbox" name="edu[]" value="Высшее">Высшее <br/>
        <input type="checkbox" name="edu[]" value="Второе высшее">Второе высшее <br/><br/>
    <label for="comment">
        Комментарий<br/>
        <textarea name="comment" id="comment" cols="30" rows="5"></textarea>
    </label><br/><br/>
    <input type="submit" name="" value="Отправить">
</form>

Обратите внимание на квадрантные скобки в атрибуте name наших checkbox-ов, эти скобки означают что вы можете передать несколько значений под одним именем в данном случае edu (сокращение от английского education — образование) . Если заполнить форму и выбрать несколько образований, параметр edu будет передан как массив:

Array
(
    [username] => Иван
    [age] => 20
    [position] => менеджер
    [edu] => Array
        (
            [0] => Среднее
            [1] => Средне-специальное
            [2] => Высшее
        )

    [comment] => Тестовый комментарий
)

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

Особенности отправки checkbox

Обратите внимание на прошлый пример. При использовании checkbox не нужно создавать отдельное поле с пустым value как это было у selectbox. Дело в том, что если вы не выбрали ни одно значение из предложенных checkbox-ов, этот параметр вовсе не будет отправлен на сервер. Это следует учитывать в вашем скрипте и делать дополнительную проверку на существование переменной в глобальном массиве $_GET.

Передача файла

Для отправки файла средствами веб-формы предусмотрено специальное поле file, давайте добавим его в нашу форму. Но прежде чем это сделать, нужно внести изменения в тег <form> а именно:

  1. Изменить метод передачи данных на post
  2. Добавить атрибут enctype=«multipart/form-data»

Вот так:


<form action="/script.php" enctype="multipart/form-data" method="post">
    <label for="username">
         Имя пользователя<br/>
        <input type="text" name="username" id="username">
    </label><br/>
    <label for="age">
        Возраст<br/>
        <input type="number" name="age" id="age">
    </label><br/>
    <label for="position">
        Должность<br/>
        <input type="text" name="position" id="position">
    </label><br/>
        Образование<br/>
        <input type="checkbox" name="gov[]" value="Среднее">  Среднее <br/>
        <input type="checkbox" name="gov[]" value="Средне-специальное">  Средне-специальное <br/>
        <input type="checkbox" name="gov[]" value="Высшее">  Высшее <br/>
        <input type="checkbox" name="gov[]" value="Второе высшее">  Второе высшее <br/><br/>
    <label for="resume">
        Резюме<br/>
        <input type="file" name="resume" id="resume">
    </label><br/>
    <label for="comment">
        Комментарий<br/>
        <textarea name="comment" id="comment" cols="30" rows="5"></textarea>
    </label><br/><br/>
    <input type="submit" name="" value="Отправить">
</form>

Так же следует отметить, что данные о переданном на сервер файле попадают в отдельный глобальный массив $_FILES откуда мы можем их получить и корректно обработать файл. Я добавил вот такой код перед формой, чтобы наглядно продемонстрировать содержимое глобальных массивов $_POST и $_FILES:


if($_POST){
    echo '<pre>';
    print_r($_POST);
    echo '</pre>';
}

if($_FILES){
    echo '<pre>';
    print_r($_FILES);
    echo '</pre>';
}

Отправляем форму, получаем такую картину:

Отправка файла через форму
Как видите поле resume не попало в массив $_POST а сразу перешло в массив $_FILES. Php сам определяет какие данные, каким методом и какого типа были переданы и распределяет их по доступным глобальным массивам.

Безопасность

Одно из главных правил при обработке форм на php — НИКОГДА не доверяйте данным пришедшим с формы. Вам нужно обязательно отфильтровать каждое поле на стороне сервера, даже если на клиенте у вас стоит jQuery валидатор и прочие javascript обработчики призванные предотвратить некорректную или злонамеренную отправку данных через форму на сервере.

Существует множество способов фильтрации данных, один из приёмов это так называемый «Белый список» когда вы точно знаете что в переменной age у вас может быть только целочисленное значение в диапазоне от 18 до 60, вы можете проверить переменную на int а так же входит ли число в заданный диапазон.


if(is_numeric($_POST['age'])){
    $age = intval($_POST['age'];
    if($age >= 18 && $age <= 60){
        // всё ок
    }
}
Поле email можно проверять при помощи регулярного выражения на соответствие определённому шаблону, например:

if (preg_match('/[0-9a-z]+@[a-z]/', $_POST['email'])) {
    //email введён верно
}

И тому подобное. Всегда помните что все данные приходящие из формы несут потенциальную опасность и их нужно тщательно проверить. А на этом всё. По мере работы буду добавлять в статью «живые примеры» и детали. Желаю удачи!

Функции и конструкции языка использованные в статье: intval(), is_numeric()

Вам также могут понравиться

Современные способы заработка на сайтах

Современные способы заработка на сайтах

Не для кого не секрет, что в современном мире вы можете зарабатывать определённые деньги на своём сайте ничего не продавая. Говоря «ничего не продавая», я имею ввиду классическую схему, когда вы продаёте свои услуги, перепродаёте товар (предварительно закупая или используя схемы прямой поставки «дроп-шиппинга») или что-то производите. В статье рассмотрим методы, которые не требуют от вас подобных действий. И так, рассмотрим основные методы в порядке возрастания их сложности и времени которое требуется от владельца сайта.

Пользовательский тип свойств инфоблока в 1С Битрикс

Пользовательский тип свойств инфоблока в 1С Битрикс

В дополнение к статье о создании собственного типа пользовательских полей хочу рассказать как делать аналогичные свойства для информационных блоков, т.к. эти свойства относятся к другому модулю, а именно «информационные блоки» (iblock).

Условные операторы в PHP

Условные операторы в PHP

Добрались до логики выполнения программы. И так условные операторы (по другому операторы ветвления) позволяют нам организовать определённое поведение программы в зависимости от входных параметров (данных вводимых пользователем, результатом работы вспомогательных функций). Вся логика в языках программирования основана на Алгебре Буля. 

Комментарии
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке

Самые читаемые

Тонкая настройка SEO для результатов фильтрации каталога битрикс

Тонкая настройка SEO для результатов фильтрации каталога битрикс

Одним из преимуществ интернет-магазинов на 1С Битрикс на мой взгляд является наличие не так давно до...

Основы SEO оптимизации сайта

Основы SEO оптимизации сайта

Эта статья не истина в последней инстанции, а лишь набор правил которые я применяю при создании/испр...

Собственный тип пользовательских полей в 1С Битрикс

Собственный тип пользовательских полей в 1С Битрикс

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