Pull to refresh

Переменные переменных. Свойства свойств. Инициализация данных из суперглобальных массивов легко и просто

Reading time3 min
Views4K

Есть интересная идея реализации некоторого обработчика суперглобальных массивов, на примере суперглобального массива $_REQUEST.
Простой способ получить, обработать, обезопаситься за полученные данных с формы и тп. выглядит:

	if (!isset($_REQUEST['var']))
		$var = NULL;
	else
		$var = $_REQUEST['var']; // перед присваиванием нужно прогнать через фильтр

Ну ясное дело, каждый уважающий себя фреймворк, сделает это красивее, тобишь к примеру отдельный статический метод класса, который можно использовать в любом месте проекта, удобно достав нужное нам значение по имени:

	class Request {
		public static function GetVarRequest( $var ){
			if (!isset($_REQUEST[$var]))
				$var = NULL;
			else
				$var = $_REQUEST['var'];	// перед присваиванием нужно прогнать через фильтр
			return $var;
		}
	}

	$var = Request::GetVarRequest('var');

И наконец подходим к сути. Есть такое понятие в PHP как "Переменные переменных" (символические ссылки), что и сподвигнуло меня на это решение. Копипастить описание и примеры нет смысла, кто не знаком сюда.

Как это связано с вышеизложенным? Возможно я придумал велосипед, но всё же. Сразу же приведу кусок рабочего решения:

	// будем считать, что данные пришли из формы
	$_REQUEST[ 'var1' ] = 'VAR1';
	$_REQUEST[ 'var2' ] = 'VAR2';
	$_REQUEST[ 'var3' ] = 'VAR3';
	echo '<pre>'; print_r( $_REQUEST ); echo '</pre>';
	$r = $_REQUEST;
	$k = array_keys( $r );
	$c = count( $r );
	for ( $i = 0; $i < $c; $i++ ){
		$v = $k[ $i ];
		$$v = $r[ $k[ $i ] ];		// перед присваиванием нужно прогнать через фильтр
	}
	echo '<br />var1 - '.$var1;	// вывод: "var1 - VAR1"
	echo '<br />var2 - '.$var2;	// вывод: "var2 - VAR2"
	echo '<br />var3 - '.$var3;	// вывод: "var3 - VAR3"

Более того, это можно проделать со свойствами класса:

	class VarsVar {
		// можно оставить абсолюно пустым
	}

	$obj = new VarsVar();

	$_REQUEST[ 'var1' ] = 'VAR1';
	$_REQUEST[ 'var2' ] = 'VAR2';
	$_REQUEST[ 'var3' ] = 'VAR3';
	echo '<pre>';print_r($_REQUEST);echo '</pre>';
	$r = $_REQUEST;
	$k = array_keys( $r );
	$c = count( $r );
	for ( $i = 0; $i < $c; $i++ ){
		$v = $k[ $i ];
		$obj->$v = $r[ $k[ $i ] ];
	}
	echo '<br />var1 - '.$obj->var1;	// вывод: "var1 - VAR1"
	echo '<br />var2 - '.$obj->var2;	// вывод: "var2 - VAR2"
	echo '<br />var3 - '.$obj->var3;	// вывод: "var3 - VAR3"

То есть обрамив это дело в статик функцию, передав в нее объект экземпляра класса (ещё не проверено на 100%), можно производить инициализацию где угодно и когда угодно:

	class Request {
		public static function GetVarRequest( $obj ){
			$r = $_REQUEST;
			$k = array_keys( $r );
			$c = count( $r );
			for ( $i = 0; $i < $c; $i++ ){
				$v = $k[ $i ];
				$obj->$v = $r[ $k[ $i ] ];
			}
		}
	}

	class VarsVar {}

	$obj = new VarsVar();
	Request::GetVarRequest( $obj ); // В PHP 5 уже не нужно явно передавать объекты или присваивать их по ссылке, это делается автоматически.

Итак, подводим итоги.
Минусы:
  • нет защиты (кроме постоянного юза «if(isset($var))...» ) от использования отсутствующих переменных, по причине отсутствия оных в самом $_REQUEST, что в свою очередь повлечёт за собой фатал эрор в скрипте;

Плюсы:
  • защита действует, если в классе объявлены используемые свойства;
  • полностью автоматизированная инициализация;
  • возможность сразу же использовать нужные нам переменные/свойства;


Вывод: универсальный и очень простой способ получения данных из $_REQUEST без лишнего гемора использовать можно, только на свой страх и риск. Если вы уверенны, что данные 100% всегда доходят и в случае использования ООП инициализированы свойства класса, то этот метод как флаг вам в руки=))

Данное решение ещё не прошло испытание боем, так как озарило только сегодня и делюсь с вами. Здесь действует парочка простых правил:
  • желательно использовать ООП, тобишь классы с их свойствами;
  • имена ключей в $_REQUEST должны совпадать с именами выших свойств класса;
  • свойства должны быть public;

И конечно бредовая ремарочка из мира фантазий. Если бы в ядро PHP зашили к примеру такой вид переменных $$$var, обращаясь к которым не выскакивало бы ероров из-за отсутствия их инициализации, а наоборот, сразу же создавались бы такие переменные со значением NULL, то предложенный мною способ работал бы безукаризненно.
Tags:
Hubs:
Total votes 42: ↑10 and ↓32-22
Comments42

Articles