Переменные переменные в PHP – Какова их цель?

В PHP есть функциональность, официально называемая « Переменные переменные », где можно назначить переменные переменные. Переменная-переменная принимает значение одной переменной в качестве имени для новой переменной! Например:

$name='Joe'; $$name='Smith'; // could also be written as ${$name}='Smith' 

Первая переменная $ name содержит значение «Joe», а вторая – переменная с именем $ Joe со значением «Smith». Учтите, что переменные PHP чувствительны к регистру!

Я никогда не использовал эту функциональность и не вижу в этом цели. Может ли кто-нибудь объяснить мне, где эта функциональность может быть использована в качестве хорошей практики?

Иногда нам нужно программное обеспечение, которое является чрезвычайно гибким и что мы можем параметризовать. Разумеется, вы должны подготовить все это, но часть этого происходит только от ввода пользователем, и у нас нет времени менять программное обеспечение только потому, что пользователю нужен новый вход.

С переменными переменными и переменными функциями вы можете решать проблемы, решить их гораздо труднее.

Быстрый пример:

Без переменных переменных:

 $comment = new stdClass(); // Create an object $comment->name = sanitize_value($array['name']); $comment->email = sanitize_values($array['email']); $comment->url = sanitize_values($array['url']); $comment->comment_text = sanitize_values($array['comment_text']); 

С переменными переменными

 $comment = new stdClass(); // Create a new object foreach( $array as $key=>$val ) { $comment->$key = sanitize_values($val); } 

Это имеет некоторые применения, когда ссылки на переменные внутри классов, и есть некоторые случаи, когда они действительно могут потребоваться (например, в __get() , __set() , __isset() и __unset() ). Однако в большинстве случаев их нецелесообразно использовать для глобальных переменных.

Имейте в виду, что НИКОГДА не следует напрямую принимать вход для конечных пользователей, когда дело доходит до переменных переменных. Вместо этого следует использовать функцию обертки, чтобы разрешить использование только определенных входных данных.

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

Вы можете использовать для чего-то вроде

 $labels = array( 'first_name" => 'First Name", 'middle_name" => 'Middle Name", 'last_name" => 'Last Name", 'phone" => 'Phone"); foreach($labels as $field => $label) { echo '<div id='field'><label for='$field'>$label</label> <input id='$field' name='$field' type='text' value='".$$field."' /></div>"; } 

На мой взгляд, это плохая старая школа …

Согласно ответу @Faiz (который я принял как формальный ответ на мой вопрос), я создал следующий пример.

Если бы у меня был класс Customer:

 class Customer { public $firstname; public $lastname; public $country; public $gender; ... } 

и веб-форму HTML с полями INPUT / SELECT с именами «firstname», «lastname», «country», «gender» …

 <form action="..." method="post"> <input type="text" name="firstname" value="" /> <input type="text" name="lastname" value="" /> <select name="country"> <option value="AL">Albania</option> <option value="BE">Belgium</option> <option value="HR">Croatia</option> ... </select> <input type="radio" name="gender" value="M" />Man <input type="radio" name="gender" value="F" />Woman ... <input type="submit" value="Submit" /> </form> 

как правило, в моем скрипте действий я буду сопоставлять эти поля форм в переменные класса один за другим как:

 $Customer=new Customer(); $Customer->firstname=$_POST['firstname']; $Customer->lastname=$_POST['lastname']; $Customer->country=$_POST['country']; $Customer->gender=$_POST['gender']; ... $Customer->create(); 

Но используя переменные переменные, я могу легко сопоставить все значения ассоциативных массивов (их может быть много, которые подвержены ошибкам) ​​в переменные класса, используя следующий один цикл foreach;

 $Customer=new Customer(); foreach($_POST as $key=>$value) $Customer->$key=$value; $Customer->create(); 

Примечание. Для простоты и ясности ответа (логики) я опустил санацию значений $ _POST.