Переменные переменные кажутся довольно крутыми, но я не могу придумать сценарий, в котором можно было бы использовать их в рабочей среде. Что такое такой сценарий? Как они были использованы?
Его цель, я думаю, заключается в том, чтобы позволить начинающим программистам динамически изменять данные без использования «сложных вещей», таких как составные типы (массивы и объекты).
Я никогда их не использую.
Переменная переменная по существу является массивом (map / dictionary). Ниже приведены эквивалентные идеи:
<?php $foo = array('a' => 1); $bar = 'a'; echo $foo[$bar]."\n"; $foo_a = 1; $bar = 'a'; $vv = "foo_$bar"; echo $$vv."\n"; ?>
Таким образом, если вы переносите «переменные переменные» в родительский массив, вы можете покончить с ними.
Я видел, как люди используют переменные свойства внутри классов:
<?php class Foo { private $a = 1; public function __get($key) { if (isset($this->$key)) return $this->$key; } } $foo = new Foo(); echo $foo->a; ?>
Но опять-таки вы можете использовать массив:
<?php class Foo { private $props = array('a' => 1); public function __get($key) { if (array_key_exists($key, $this->props)) return $this->props[$key]; } } $foo = new Foo(); echo $foo->a; ?>
И внешние классы:
<?php class Foo { public $a = 1; } $foo = new Foo(); $prop = 'a'; echo $foo->{$prop}; ?>
Таким образом, вы никогда не имеете «использовать» переменные переменные или свойства переменных при написании собственного управляемого кода. Мои личные предпочтения – никогда не использовать переменные переменные. Я иногда использую переменные свойства, но предпочитаю использовать массивы, когда я буду обращаться к данным таким образом.
Лично я использую их довольно часто. Все вызовы следующих типов используют переменные переменные:
$foo->$bar = 'test'; $foo->$bar(); $bar();
Поэтому в любое время, когда вы выполняете динамический вызов метода / функции, вы используете переменные переменные …
Общим для этого является доступ к защищенным свойствам с помощью метода __get
magic. Я часто видел следующее:
public function __get($name) { return isset($this->$name) ? $this->$name : null; }
Который по определению использует переменные переменные для обеспечения доступа для чтения к защищенным членам …
Я никогда не использовал синтаксис $$var
(и не думаю, что когда-либо буду). Я видел, что он использовался для доступа к глобальным переменным по имени global $$name; echo $$name;
global $$name; echo $$name;
, но то же самое можно сделать с $_GLOBALS[$name]
, так что это не очень хороший случай использования (не говоря уже о том, что использование глобальных переменных обычно рассматривается как плохая практика) …
Подумайте об этом для использования в системе шаблонов, где вы используете файлы PHP, и вам нужно установить в переменных:
function fetch_template($file, $vars){ $ret = 'File not loaded.'; if(file_exists(TEMPLATE_PATH.$file)){ //could do this with extract() but I am showing you foreach($vars as $varName => $value){ ${$varName} = $value; } ob_start(); include(TEMPLATE_PATH.$file); $ret = ob_get_contents(); ob_end_clean(); } return $ret; }
Предполагая, что вы использовали эти имена переменных в своем шаблоне, вы можете вызвать его и передать в него переменные для использования.
echo fetch_template('hi_there.tpl', array('name'=>'JJ'));
Затем в вашем шаблоне:
Hello <?php echo $name; ?>!
Я нашел его полезным в одном сценарии. Я получал результаты API YouTube в формате JSON, например
$obj->media$title => Video title
Поэтому я использовал его как
$mt = 'media$title'; $obj->$mt ;
Так что это сработало для меня здесь 🙂
В основном я использую его для уменьшения копий-пасты при дезинфекции данных get / post в начале файла php: он превращает дезинфицированные переменные с именами:
$fields=array('age','name','gender','email','username'); foreach($fields as $field) { if (empty($_REQUEST[$field] === false) ${$field} = sanitize($_REQUEST[$field]); else ${$field} = ''; }
вместо всех этих строк:
if (empty($_GET['age']) === false) $age= sanitize($_GET['age']); else $age= ''; if (empty($_GET['name']) === false) $name= sanitize($_GET['name']); else $name = ''; if (empty($_GET['gender']) === false) $gender= sanitize($_GET['gender']); else $gender= ''; if (empty($_GET['email']) === false) $email= sanitize($_GET['email']); else $email= ''; if (empty($_GET['username']) === false) $username= sanitize($_GET['username']); else $username= '';
Я надеюсь, что это помогает