То, что параметры в PHP надо фильтровать, думаю знают все. Наиболее распространённая задача — фильтрация числовых параметров, которые в большинстве своём являются целыми числами, и в подавляющем большинстве еще и числами натуральными, то есть большими нуля. Хочу поделиться своим способом проверки на натуральные числа, может кому-то он покажется более удобным, чем его собственный.
Например возьмём такой адрес: http://example.com/price.php?product=859844&page=99.
Скрипт выводит список цен в магазинах для товара product, необязательный параметр page указывает номер страницы. Если page не указан, и url выглядит как http://example.com/price.php?product=859844, тогда выводим первую страницу.
До версии PHP 5.2.0 задачу можно было решить таким нехитрым образом.
// Функция получения параметра, являющегося натуральным числом
// $arr = массив параметров ($GET или $POST), $name = имя параметра,
// Функция возвращает значение параметра, либо $default если параметр отсутствует, либо некорректен
function get_param_nat($arr, $name, $default=null) {
if (!isset($arr[$name]))
return $default;
// Проверяем очень нехитрым способом, конвертируем параметр в число, потом обратно в строку
// Если все нормально, то полученная строка должна совпадать с исходным значеним параметра
$val = $arr[$name];
$intval = intval($val);
// В нагрузку проверяем, что число у нас получилось больше нуля
if (strval($intval) !== $val || $intval < 1)
return $default;
return $intval;
}
// Проверяем параметр product
if (($product = get_param_nat($_GET, 'product')) === null)
die('Product not found');
// Получаем номер страницы
$page = get_param_nat($_GET, 'page', 1);
Начиная в версии 5.2.0 в PHP появилась группа функций Filter: filter_var, filter_input, filter_var_array и несколько других. Функции могут проверять переменные на целые числа, числа с плавающей точкой, e‑mail, ip‑адреса, url и т.д., а также очищать строки в соответствии заданным параметрам.
Перепишем код с использование функции filter_input.
function get_param_nat($type, $name, $default=null) {
$val = filter_input($type, FILTER_VALIDATE_INT, array('min_range' => 1, 'max_range' => PHP_INT_MAX ));
// filter_input возвращает false, если фильтрация закончилась неудачей, или null, если переменная неопределена
if ($val === null || $val === false)
return $default;
return $val;
}
// Проверяем параметр product
if (($product = get_param_nat(INPUT_GET, 'product')) === null)
die('Product not found');
// Получаем номер страницы
$page = get_param_nat(INPUT_GET, 'page', 1);
Небольшое тестирование показало, что по скорости работы два варианта функции get_param_nat практически одинаковы, а в случае отсутствия параметра, например не будет указано page, первый вариант будет отрабатывать даже несколько быстрее.
Поэтому вам решать, что использовать. Я лично использую первую функцию, мне она как‑то ближе и понятнее.
Ну и небольшое лирическое отступление в конце. Во избежании дублирования страницы для поисковиков, например без page и с page=1, рекомендую в разделе head страницы указывать канонический url. Выглядеть это будет примерно так:
<head>
...
<link rel="canonical" href="/price.php?product=<?= $product ?><?= $page!=1 ? "&page=$page" : null ?>">
...
</head>