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 или POSTSearch 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=dateSearch 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-свойства для поддержки разных языков.