Функция для обработки входящих данных

Собственно вот и обещанная мной функция для обработки данных, поступающих от пользователя. Для получения одной переменной вызываем так (какие аргументы передавать думаю и так ясно):

<?php
$var = import_var('var','G','INT',3);
?>

Для получения одновременно нескольких однотипных переменных вызов функции немного отличается:

<?php
extract(import_var(array('var1','var2','var3'),'G','INT',3));
echo $var1;
echo $var2;
echo $var3;
?>


Вот код функции:

<?php
function import_var($name,$source,$type,$maxlen=0) {
	$retarr=array();
	if(is_array($name)) { // если нужно обработать массив с именами
		foreach($name as $v) {
			$retarr[$v] = import_var($v,$source,$type,$maxlen);
			// рекурсивно запускаем себя же
		}
	if(sizeof($retarr)>0) return $retarr; // возвращаем массив
	}
	// если нужно обработать одну переменную
	switch($source) {
		case 'G':
			if (isset($_GET[$name])) {
				$var=$_GET[$name];  // из GET
			}
		break;
		case 'P':
			if (isset($_POST[$name])) {
				$var=$_POST[$name];  // из POST
			}
		break;
		case 'C':
			if (isset($_COOKIE[$name])) {
				$var=$_COOKIE[$name];  // из Cookie
			}
		break;
	}

	if(!isset($var)) return false; // если переменная существует

	if(is_array($var)) return false; // и если это не массив...

	if(get_magic_quotes_gpc()) $var = stripslashes($var);
	// убираем лишние бэкслэши

	if(empty($var)) return false; // если переменная пуста

	if ($maxlen>0) $var = substr($var,0,$maxlen); //обрубаем лишнее

	switch($type) { // теперь обрабатываем в соответствии с типом
		case 'INT' : // число integer
			return is_integer($var) ? $var : intval($var);
		break;
		case 'NUM' : // число integer или float
			return is_numeric($var) ? $var : false;
		break;
		case 'HTML' : // текст, в котором могут содержаться тэги
			return trim(htmlspecialchars($var));
		break;
		case 'SQL' : // строка, которая попадет в SQL-запрос
			return mysql_real_escape_string(htmlspecialchars($var));
		break;
		case 'MAIL'	: // email-адрес
			return preg_match('/^[\w\.\-]+@\w+[\w\.\-]*?\.\w{2,4}$/',$var) ? $var : false;
		break;
		case 'ALPHA' : // только буквенные символы
			return preg_match("/^[а-яА-ЯёЁa-zA-Z]+$/",$var) ? $var : false;
		break;
		case 'ALPHANUM' : // числовые и буквенные символы
			return preg_match("/^[а-яА-ЯёЁa-zA-Z0-9]+$/",$var) ? $var : false;
		break;
		case 'MD5' : // md5-хэш
			return preg_match("/^[a-fA-F0-9]{32}+$/",$var) ? $var : false;
		break;
		case 'SHA1' : // sha1-хэш
			return preg_match("/^[a-fA-F0-9]{40}+$/",$var) ? $var : false;
		break;
		case 'BOOL': // булева величина
			return ($var=="1" || $var=="true" || $var=="on") ? true : false;
		break;
	}
}
?>

Хочу отметить, что данная функция не принимает массивы данных, так как их обработка весьма затруднительна, ввиду того, что элементы могут иметь разные типы данных, и одним вызовом функции корректно обработать весь массив никак не получится.

Жду Ваших комментариев с предложениями по поводу дополнительных типов данных, которые также могут быть востребованы.


17 комментариев

  1. c0nst, 16. мая 2008, 19:13

    > return addslashes(htmlspecialchars($var));
    а если запрос без кавычек?) -1+union+select+…/*
    спецсимволов тут нет, по этому htmlspecialchars() не спасет, от addslashes тоже нет толку. Функция подойдет для запросов типа insert, update. В случае с select, лучше использовать mysql_escape_string(), имхо.

     
  2. Raz0r, 16. мая 2008, 23:21

    а чем mysql_escape_string() отличается от addslashes()? По сути одинаковые функции с той лишь разницей, что первая также добавляет слэши перед символами перевода строки. Если в запросе переменная без кавычек, то это, как правило, числовое значение и здесь необходимо вызывать функцию, указывая тип INT, а не SQL.

     
  3. Kuzya, 17. мая 2008, 21:14

    mysql_escape_string() технически помоему не отличается. Гдето встречал описание, если найду — подкину. А функция оч интересная =)

     
  4. c0nst, 17. мая 2008, 22:32

    http://ru2.php.net/mysql_escape_string
    http://ru2.php.net/addslashes
    искать долго не нужно 🙂

     
  5. Raz0r, 17. мая 2008, 23:03

    В документации сказано, что для экранирования спецсимволов в строках с их последующей вставкой в SQL-запросы можно использовать любую из этих двух функций, причем вместо mysql_escape_string() рекомендуется использовать mysql_real_escape_string(), которая также учитывает текущую кодировку соединения. Короче говоря, результат работы этих функций почти одинаковый — главное здесь другое: не забывать их использовать =)

     
  6.  

    […] уже не раз излагал свои мысли по поводу принципов грамотной фильтрации входящих данных, этот пост будет своеобразным […]

     
  7.  

    […] уже не раз излагал свои мысли по поводу принципов грамотной фильтрации входящих данных, этот пост будет своеобразным […]

     
  8. ole6ka, 9. января 2009, 14:41

    тут есть проблема одна,, при исползованье var как типа int
    пример
    /function.php?var=dhs
    функция выдаёт знчение false, каторая равна 0

     
  9. Raz0r, 12. января 2009, 12:06

    var_dump(intval(‘abc’));
    ->
    int(0)

    проблемы не вижу, если правильно проверять результат работы функции, то все будет нормально =)

     
  10. Raz0r, 13. марта 2009, 21:54

    UPDATE: заменил небезопасные вызовы eregi() на preg_match()

     
  11. Emil, 19. апреля 2009, 22:10

    Как насчет русских букв?

     
  12. Zerg HC, 10. сентября 2009, 11:19

    строка
    if ($maxlen>0) substr($var,0,$maxlen); //обрубаем лишнее
    не должна ли выглядеть как
    if ($maxlen>0) $var = substr($var,0,$maxlen); //обрубаем лишнее
    для php6 не нужна строка
    if(get_magic_quotes_gpc()) $var = stripslashes($var);

    ну а сам скрипт на отлично, спасибо

     
  13. Raz0r, 10. сентября 2009, 14:50

    Спасибо, обновил

     
  14. Franc, 3. января 2010, 0:26

    Есть один момент.
    Если использовать import_var((‘litter’, ‘G’, ‘ALPHA’, 1) то русский шрифт обрежется.
    заменив длину на 2 пройдет две латинских буквы…

     
  15. Raz0r, 3. января 2010, 13:48

    Проверил, с кириллицей все правильно

     
  16. Franc, 4. января 2010, 0:32

    воспроизводится так
    echo ‘fff‘;
    print_r(import_var(‘litter’, ‘G’, ‘ALPHA’, 1));
    именно при проходе по ссылке. Возможно дело в кодировке.

     
  17. Barma, 20. февраля 2010, 16:23

    Доброе время суток. Данная функция не работает в PHP 5.3. Только что столкнулся с данной проблемой.
    1) в новой версии иначе работает тернарный оператор! Заменил его на if else.
    2) Функция не создает новую переменную! Внутри функции, перед самой выдачей результатов, переменная $var содержит значение, но выражение return $var; не создает новую переменную, содержащую в себе значение! Никак не могу понять в чем проблема.

     

Write a comment: