Обработка пользовательского ввода в PHP

Раздел: Основы PHP -> Обработка ввода данных в PHP

Способы получения данных от пользователя

Использование filter_input для безопасного извлечения

Как получить значение из внешнего источника с автоматической проверкой типа?

Функция filter_input позволяет извлечь данные из суперглобальных массивов (INPUT_GET, INPUT_POST, INPUT_COOKIE и другие) с применением фильтра. Это наиболее надёжный способ, так как он объединяет получение и валидацию в одном вызове.

<?php
// Получение целого числа из GET параметра 'id'
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($id === false || $id === null) {
    // обработка ошибки
    echo 'Некорректный id';
} else {
    echo 'Получен id: ' . $id;
}
?>

Php ввел (ввод данных в php)

При запросе page.php?id=42 выведет: Получен id: 42
При id=abc выведет: Некорректный id

Поддерживаются фильтры для целых чисел, строк с санитизацией, email, URL и других. При отсутствии параметра функция вернёт null, а при неверном типе - false.

Типичные ошибки: Путаница между false и null. Необходимо использовать строгое сравнение (===). Если параметр может быть равен 0, проверка через empty() приведёт к ложному срабатыванию.

<?php
$count = filter_input(INPUT_POST, 'count', FILTER_VALIDATE_INT);
if ($count === false) {
    // неверный тип или ошибка
} elseif ($count === null) {
    // параметр отсутствует
} // иначе $count содержит целое число (возможно 0)
?>

Случаи использования: Любые формы, где известен ожидаемый тип данных. Особенно полезен при работе с числовыми идентификаторами, датами, email адресами.

Прямой доступ к $_GET и $_POST

Как получить данные из строки запроса или тела POST запроса без дополнительной обработки?

Самый простой способ - обратиться к суперглобальным массивам напрямую. Однако такой подход требует ручной проверки существования индекса и валидации.

<?php
$name = isset($_POST['username']) ? $_POST['username'] : '';
$email = $_GET['email'] ?? ''; // оператор объединения с null
?>

После получения данных их нужно очищать перед выводом или использованием в запросах.

Проблемы: Отсутствие проверки может привести к ошибкам уровня E_NOTICE. Данные не проходят фильтрацию, что создаёт риск XSS и SQL инъекций. Применяется только для отладочных целей или в строго контролируемой среде.

Использование $_REQUEST для объединённого доступа

Как получить данные независимо от метода запроса (GET или POST)?

Массив $_REQUEST содержит содержимое $_GET, $_POST и $_COOKIE. Удобен для простых скриптов, когда метод не важен. Однако его использование не рекомендуется из-за потенциальной путаницы и меньшей безопасности.

<?php
$action = $_REQUEST['action'] ?? 'default';
?>

Недостатки: Нельзя контролировать приоритет источника. Если один и тот же параметр передан и GET, и POST, поведение зависит от конфигурации (переменная variables_order). Это может привести к неожиданным результатам. Лучше явно указывать источник.

Очистка строк с помощью strip_tags и htmlspecialchars

Как удалить HTML теги и экранировать специальные символы для безопасного вывода?

Функция strip_tags удаляет все HTML и PHP теги из строки. htmlspecialchars преобразует специальные символы в HTML сущности, предотвращая внедрение скриптов.

<?php
$raw = $_POST['message'] ?? '';
$clean = strip_tags($raw);
$safe = htmlspecialchars($clean, ENT_QUOTES, 'UTF-8');
echo $safe;
?>

Ошибки: strip_tags не защищает от всех XSS атак, если в строке остаются разрешённые теги. htmlspecialchars следует применять только при выводе, а не при сохранении в БД (иначе данные будут закодированы дважды).

Валидация с помощью регулярных выражений

Как проверить, соответствует ли входная строка определённому шаблону (например, номер телефона)?

Функция preg_match позволяет задать шаблон и проверить строку на соответствие. Это подходит для сложных форматов.

<?php
$phone = $_POST['phone'] ?? '';
if (preg_match('/^\+?[1-9]\d{1,14}$/', $phone)) {
    echo 'Номер корректен';
} else {
    echo 'Неверный формат номера';
}
?>

Проблемы: Регулярные выражения могут быть медленными при большом объёме данных. Их сложно поддерживать. Рекомендуется использовать встроенные фильтры PHP, если они подходят для задачи.

Подробные примеры обработки ввода

Фильтрация массива параметров с помощью filter_input_array

Функция filter_input_array позволяет обработать сразу несколько полей, задав массив правил.

Пример
<?php
$filters = [
    'name' => FILTER_SANITIZE_STRING,
    'age'  => ['filter' => FILTER_VALIDATE_INT, 'options' => ['min_range' => 1, 'max_range' => 120]],
    'email' => FILTER_VALIDATE_EMAIL
];
$result = filter_input_array(INPUT_POST, $filters);
var_dump($result);
?>
Пример вывода при POST name=John&age=25&email=john@test.com:
array(3) {
  ["name"]=> string(4) "John"
  ["age"]=> int(25)
  ["email"]=> string(14) "john@test.com"
}

Если age=abc, то age станет false.

Обработка ввода из командной строки (CLI)

В скриптах для консоли данные можно читать через fgets из STDIN или использовать аргументы командной строки ($argv).

Пример
<?php
echo "Введите ваше имя: ";
$handle = fopen("php://stdin", "r");
$name = trim(fgets($handle));
fclose($handle);
echo "Привет, $name!\n";
// Использование аргументов:
// php script.php --name=John
$longopts  = [
    "name:",    // обязательное значение
];
$options = getopt("", $longopts);
if (isset($options['name'])) {
    echo "Аргумент name: " . $options['name'] . "\n";
}
?>
При запуске php input.php и вводе Alice:
Привет, Alice!

При запуске php input.php --name=Bob:
Аргумент name: Bob

Работа с загрузкой файлов через $_FILES

Файлы передаются через форму с enctype="multipart/form-data". Проверка типа и размера обязательна.

Пример
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['avatar'])) {
    $file = $_FILES['avatar'];
    $allowedTypes = ['image/jpeg', 'image/png'];
    if (in_array($file['type'], $allowedTypes) && $file['size'] < 2*1024*1024) {
        $dest = 'uploads/' . basename($file['name']);
        if (move_uploaded_file($file['tmp_name'], $dest)) {
            echo 'Файл загружен: ' . $dest;
        } else {
            echo 'Ошибка перемещения файла';
        }
    } else {
        echo 'Недопустимый тип или размер файла';
    }
}
?>
При успешной загрузке: Файл загружен: uploads/photo.jpg

Безопасная работа с JSON вводом

Современные API часто передают данные в JSON. Чтение потока php://input и декодирование.

Пример
<?php
$json = file_get_contents('php://input');
$data = json_decode($json, true); // ассоциативный массив
if (json_last_error() === JSON_ERROR_NONE) {
    $name = $data['name'] ?? '';
    echo 'Имя: ' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
} else {
    echo 'Неверный JSON';
}
?>
При POST с телом {"name":"Анна"} выведет: Имя: Анна

Пример фильтрации с пользовательской функцией обратного вызова

Можно использовать FILTER_CALLBACK для собственной валидации.

Пример
<?php
function validate_username($value) {
    // только буквы и цифры, длина 3-20
    if (preg_match('/^[a-zA-Z0-9]{3,20}$/', $value)) {
        return $value;
    }
    return false;
}

$username = filter_input(INPUT_POST, 'username', FILTER_CALLBACK, ['options' => 'validate_username']);
if ($username) {
    echo 'Имя пользователя: ' . $username;
} else {
    echo 'Некорректное имя';
}
?>
При POST username=JohnDoe выведет: Имя пользователя: JohnDoe
При username=Jo (слишком короткое) выведет: Некорректное имя

Ввод данных в PHP - comments

En
Php ввел (php)