PHP и поисковые запросы: извлечение параметров

Раздел: Веб-разработка -> Поисковые функции

Поисковые переменные в PHP: основные подходы

В веб-разработке поисковые функции требуют получения данных от пользователя через URL или формы. PHP предоставляет суперглобальные массивы $_GET, $_POST и $_REQUEST, но прямое обращение к ним без проверок и фильтрации может привести к уязвимостям и ошибкам. Рассмотрим наиболее надёжное решение и альтернативные варианты.

Наиболее эффективный способ - использование функции filter_input() с постоянными фильтрами FILTER_SANITIZE_* и FILTER_VALIDATE_*. Это обеспечивает санитаризацию и валидацию входных данных без необходимости писать собственные проверки.

Безопасное извлечение одной переменной

// Получение строки поиска из GET
$search = filter_input(INPUT_GET, 'q', FILTER_SANITIZE_STRING);
if ($search === null) {
    // переменная не передана
    $search = '';
} elseif ($search === false) {
    // фильтрация не удалась (неверный тип)
    $search = '';
}

Search php search author (поиск по автору в php)

Пакетное получение нескольких параметров

$defaults = [
    'q'     => '',
    'page'  => 1,
    'cat'   => ''
];
$input = filter_input_array(INPUT_GET, [
    'q'    => FILTER_SANITIZE_STRING,
    'page' => ['filter' => FILTER_VALIDATE_INT, 'options' => ['default' => 1]],
    'cat'  => FILTER_SANITIZE_STRING
]);
$input = array_merge($defaults, array_filter($input, function($v) { return $v !== false; }));

Index php act search ru (поиск с параметром ru в php)

Этот подход предотвращает внедрение вредоносного кода и гарантирует, что переменные будут иметь ожидаемые типы. При работе с базой данных полученные значения следует передавать через prepared statements (PDO или mysqli).

Частая ошибка: использование filter_input без проверки на false. Если фильтр не может обработать значение (например, невалидный int), функция вернёт false, а не ожидаемое значение. Это может вызвать непредсказуемое поведение, если false подставляется в SQL запрос или в шаблон.

Решение: всегда проверять возвращаемое значение на false или использовать аргумент 'default' в опциях фильтра.

Как получить переменную поиска напрямую из $_GET или $_POST?

Самый простой, но наименее безопасный вариант - прямое обращение:

$search = $_GET['q'] ?? ''; // если ключ не существует, будет ''

Advance search php (расширенный поиск в php)

Такой код уязвим для XSS-атак, если значение выводится на страницу без экранирования. Кроме того, оно может содержать неожиданные типы (массивы вместо строк).

Проблема: отсутствие санитаризации. Злоумышленник может передать строку с JavaScript-кодом. Решается экранированием через htmlspecialchars() при выводе.

В чём опасность использования $_REQUEST для поисковых переменных?

Массив $_REQUEST объединяет GET, POST и COOKIE. Если в форме используется метод GET и одновременно есть параметры в URL с тем же именем, результат может быть непредсказуемым.

$search = $_REQUEST['q'] ?? ''; // может получить значение из GET или POST

Search php vars (переменные поиска в php)

Ошибка: потеря контроля над источником данных. Лучше явно указывать $_GET или $_POST.

Как проверить существование переменной без ошибки?

Функция isset() проверяет, определена ли переменная и не равна ли null. Для массивов используйте array_key_exists().

if (isset($_GET['q'])) {
    $search = $_GET['q'];
} else {
    $search = '';
}

// Или через array_key_exists
if (array_key_exists('q', $_GET)) {
    $search = $_GET['q'];
} else {
    $search = '';
}

Search php search id 2 (поиск по id 2 в php)

Второй вариант не проверяет значение на null, только наличие ключа.

Как обработать массив параметров поиска (например, выбранные теги)?

Если в форме используется синтаксис с квадратными скобками (tags[]), PHP создаёт массив.

<input type="checkbox" name="tags[]" value="php">
<input type="checkbox" name="tags[]" value="mysql">

Search php key (поиск по ключу в php)

PHP-обработка с фильтрацией:

$tags = filter_input(INPUT_GET, 'tags', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY);
if (!is_array($tags)) {
    $tags = [];
}
// Теперь $tags - массив строк

Search php p 1 (поиск по странице 1 в php)

Ошибка: если параметр не передан или передан как обычная строка, filter_input с флагом FILTER_REQUIRE_ARRAY вернёт false. Нужна дополнительная проверка.

Как использовать пользовательскую функцию для извлечения переменных с типами?

Можно создать функцию, которая принимает имя параметра, источник и тип, и возвращает корректное значение.

function getSearchParam(string $name, int $source = INPUT_GET, string $type = 'string', $default = null) {
    $filter = FILTER_SANITIZE_STRING;
    if ($type === 'int') {
        $filter = FILTER_VALIDATE_INT;
        $default = (int)$default;
    } elseif ($type === 'float') {
        $filter = FILTER_VALIDATE_FLOAT;
        $default = (float)$default;
    }
    $value = filter_input($source, $name, $filter);
    if ($value === false || $value === null) {
        return $default;
    }
    return ($type === 'int') ? (int)$value : $value;
}

$q = getSearchParam('q', INPUT_GET, 'string', '');
$page = getSearchParam('page', INPUT_GET, 'int', 1);

Search php new (поиск новых записей в php)

Как построить URL поиска с параметрами?

Функция http_build_query() упрощает конструирование строки запроса из массива.

$params = [
    'q'    => 'php tutorial',
    'page' => 2,
    'sort' => 'date'
];
$url = '/search?' . http_build_query($params);
echo $url; // /search?q=php+tutorial&page=2&sort=date

Search php search id 0 (поиск по id 0 в php)

Возможная ошибка: значения не экранируются для HTML, но при выводе в атрибуте href нужно добавить htmlspecialchars().

Как безопасно передать переменные поиска в SQL запрос?

Используйте prepared statements с PDO. Никогда не вставляйте пользовательские данные напрямую в SQL.

$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$stmt = $pdo->prepare('SELECT * FROM articles WHERE title LIKE :search');
$stmt->execute([':search' => '%' . $search . '%']);
$results = $stmt->fetchAll();

Это защищает от SQL-инъекций.

Типичная ошибка: экранирование через mysql_real_escape_string() (устаревшая функция) или просто конкатенация. Используйте только PDO или mysqli с prepared statements.

Расширенные примеры работы с переменными поиска

Пример 1. Функция безопасного извлечения параметров с поддержкой массивов

Пример
function safeSearchParam($name, $source = INPUT_GET, $default = null, $isArray = false) {
    $flags = $isArray ? FILTER_REQUIRE_ARRAY : 0;
    $value = filter_input($source, $name, FILTER_SANITIZE_STRING, $flags);
    if ($value === false || $value === null) {
        return $default;
    }
    if ($isArray && is_array($value)) {
        return array_map('strip_tags', $value);
    }
    return strip_tags($value);
}

// Использование
$query = safeSearchParam('q', INPUT_GET, '');
$tags = safeSearchParam('tags', INPUT_GET, [], true);
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, ['options' => ['default' => 1]]);

Результат: переменные будут безопасно получены и очищены от HTML-тегов.

Пример 2. Построение поискового URL с динамическими параметрами

Пример
$baseUrl = '/search';
$currentParams = ['q' => 'php', 'cat' => 'backend', 'page' => 3];
// Добавление нового параметра
$newParams = $currentParams;
$newParams['sort'] = 'date';
$url = $baseUrl . '?' . http_build_query($newParams);
echo $url;
// Вывод: /search?q=php&cat=backend&page=3&sort=date
/search?q=php&cat=backend&page=3&sort=date

Пример 3. Обработка сложных поисковых фильтров с несколькими полями и типами

Пример
$filters = [
    'q'      => FILTER_SANITIZE_STRING,
    'min_price' => ['filter' => FILTER_VALIDATE_FLOAT, 'options' => ['default' => 0, 'min_range' => 0]],
    'max_price' => ['filter' => FILTER_VALIDATE_FLOAT, 'options' => ['default' => 10000, 'min_range' => 0]],
    'in_stock'  => ['filter' => FILTER_VALIDATE_BOOLEAN, 'flags' => FILTER_NULL_ON_FAILURE],
];
$input = filter_input_array(INPUT_GET, $filters);
if ($input === false) {
    // Ошибка фильтрации - возможно некорректные параметры
    $input = [];
}
// Приведение типов
$q = $input['q'] ?? '';
$minPrice = (float)($input['min_price'] ?? 0);
$maxPrice = (float)($input['max_price'] ?? 10000);
$inStock = ($input['in_stock'] === null) ? null : (bool)$input['in_stock'];

echo "Поиск: $q, Цена от $minPrice до $maxPrice, Только в наличии: ".($inStock === null ? 'все' : ($inStock ? 'да' : 'нет'));
Поиск: php, Цена от 0 до 10000, Только в наличии: все

Пример 4. Динамическое построение SQL запроса с LIKE и подготовленными выражениями

Пример
$pdo = new PDO('mysql:host=localhost;dbname=shop', 'root', '');
$search = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_STRING);
$category = filter_input(INPUT_GET, 'cat', FILTER_VALIDATE_INT, ['options' => ['default' => 0]]);
$minPrice = filter_input(INPUT_GET, 'min', FILTER_VALIDATE_FLOAT, ['options' => ['default' => 0]]);
$maxPrice = filter_input(INPUT_GET, 'max', FILTER_VALIDATE_FLOAT, ['options' => ['default' => 999999]]);

$where = [];
$params = [];

if (!empty($search)) {
    $where[] = 'name LIKE :search';
    $params[':search'] = '%' . $search . '%';
}
if ($category > 0) {
    $where[] = 'category_id = :cat';
    $params[':cat'] = $category;
}
if ($minPrice > 0) {
    $where[] = 'price >= :min_price';
    $params[':min_price'] = $minPrice;
}
if ($maxPrice < 999999) {
    $where[] = 'price <= :max_price';
    $params[':max_price'] = $maxPrice;
}

$sql = 'SELECT * FROM products';
if (!empty($where)) {
    $sql .= ' WHERE ' . implode(' AND ', $where);
}
$sql .= ' ORDER BY created_at DESC LIMIT 20';

$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);

echo "Найдено товаров: " . count($products);
Найдено товаров: 5

Пример 5. Пагинация с сохранением поисковых параметров

Пример
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, ['options' => ['default' => 1, 'min_range' => 1]]);
$perPage = 10;
$query = filter_input(INPUT_GET, 'q', FILTER_SANITIZE_STRING);

// Сбор всех текущих GET параметров, кроме page
$params = $_GET;
unset($params['page']);
$baseLink = '/search?' . http_build_query($params);

// Генерация ссылок на соседние страницы
$prevLink = ($page > 1) ? $baseLink . '&page=' . ($page - 1) : null;
$nextLink = $baseLink . '&page=' . ($page + 1);

echo "Страница $page
"; if ($prevLink) { echo "Назад "; } echo "Вперёд";
Страница 2
Назад Вперёд

Пример 6. Использование regex для валидации поискового запроса

Пример
$query = filter_input(INPUT_GET, 'q', FILTER_SANITIZE_STRING);
// Разрешаем только буквы, цифры и пробелы
if (preg_match('/^[\\p{L}\\p{N}\\s]+$/u', $query)) {
    echo "Корректный запрос: $query";
} else {
    echo "Некорректные символы в запросе";
}

Примечание: используйте Unicode-свойства для поддержки разных языков.

Переменные поиска в PHP - comments

En
Search php vars (php)