In PHP there's a functionality officially called "Variable Variables" where one can assign variable variables. A variable variable takes the value of one variable as the name for a new variable! For example:
在PHP中,有一种功能被正式称为“变量变量”,人们可以在其中分配变量。变量变量以一个变量的值作为新变量的名称!例如:
$name='Joe';
$$name='Smith'; // could also be written as ${$name}='Smith'
The first variable $name contains the value 'Joe', while the second is variable named $Joe with the value 'Smith'. Take into account that PHP variables are case-sensitive!
第一个变量$name包含值“Joe”,第二个变量名为$Joe,值为“Smith”。考虑到PHP变量是区分大小写的!
I've never used this functionality and do not see the purpose for that. Could someone explain to me where this functionality could be exploited as a good practise?
我从未使用过这个功能,也没有看到它的目的。有人能向我解释一下在哪里可以利用这个功能作为一个好的实践吗?
4 个解决方案
#1
4
Sometimes we need software that is extremely flexible and that we can parametrize. You have to prepare the whole thing, of course, but part of it just comes from user input, and we have no time to change the software just because the user needs a new input.
有时我们需要非常灵活的软件,我们可以参数化它。当然,你必须准备好所有的东西,但其中一部分只是来自用户输入,我们没有时间去改变软件,因为用户需要一个新的输入。
With variable variables and variable functions you can solve problems that would be much harder to solve without them.
有了变量和变量函数,你就可以解决没有它们很难解决的问题。
Quick Example:
Without variable variables:
$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']);
With variable variables
$comment = new stdClass(); // Create a new object
foreach( $array as $key=>$val )
{
$comment->$key = sanitize_values($val);
}
#2
0
This has some uses when referencing variables within classes, and there are some cases where these can actually be required (such as in __get()
, __set()
, __isset()
, and __unset()
). However, in most cases it is unwise to use them on global variables.
当在类中引用变量时,这有一些用途,并且在某些情况下,这些变量实际上是必需的(例如在__get()、__set()、__isset()和__unset()中)。然而,在大多数情况下,在全局变量上使用它们是不明智的。
Be aware that you should NEVER directly accept end-user input when it comes to variable variables. Instead a wrapper function should be used to ensure that only specific inputs are allowed.
注意,当涉及到变量时,不应该直接接受终端用户的输入。相反,应该使用包装函数来确保只允许特定的输入。
In most cases, variable variables are not required, and it is recommended that you avoid them when possible.
在大多数情况下,不需要变量,建议尽可能避免变量。
#3
0
You can use for something like
你可以用在类似的东西上
$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>";
}
In my opinion is bad old school...
在我看来,这是糟糕的老学校……
#4
0
According to @Faiz answer (which I accepted as the formal answer to my question) I created the following sample example.
根据@Faiz的回答(我接受为我的问题的正式回答),我创建了以下示例示例。
If I had the class Customer:
如果我有班级客户:
class Customer
{
public $firstname;
public $lastname;
public $country;
public $gender;
...
}
and the web HTML form with INPUT/SELECT fields having names 'firstname','lastname','country', 'gender'...
以及带有输入/选择字段的web HTML表单,这些字段的名称有“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>
usually in my action script I would map these form fields into class variables one by one as:
通常在我的动作脚本中,我会将这些表单字段逐一映射到类变量中,如下所示:
$Customer=new Customer();
$Customer->firstname=$_POST['firstname'];
$Customer->lastname=$_POST['lastname'];
$Customer->country=$_POST['country'];
$Customer->gender=$_POST['gender'];
...
$Customer->create();
But using variable variables I can easily map all associative array values (there could be a lot of them which is error prone) into class variables using the following one line foreach loop;
但是通过使用变量变量,我可以很容易地将所有关联数组值(其中有很多是容易出错的)映射到类变量中,使用下面的一行foreach循环;
$Customer=new Customer();
foreach($_POST as $key=>$value) $Customer->$key=$value;
$Customer->create();
Note: For the sake of answer (logic) simplicity and clearness I omitted $_POST values sanitization.
注意:为了简单明了地回答(逻辑),我省略了$_POST值清理。
#1
4
Sometimes we need software that is extremely flexible and that we can parametrize. You have to prepare the whole thing, of course, but part of it just comes from user input, and we have no time to change the software just because the user needs a new input.
有时我们需要非常灵活的软件,我们可以参数化它。当然,你必须准备好所有的东西,但其中一部分只是来自用户输入,我们没有时间去改变软件,因为用户需要一个新的输入。
With variable variables and variable functions you can solve problems that would be much harder to solve without them.
有了变量和变量函数,你就可以解决没有它们很难解决的问题。
Quick Example:
Without variable variables:
$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']);
With variable variables
$comment = new stdClass(); // Create a new object
foreach( $array as $key=>$val )
{
$comment->$key = sanitize_values($val);
}
#2
0
This has some uses when referencing variables within classes, and there are some cases where these can actually be required (such as in __get()
, __set()
, __isset()
, and __unset()
). However, in most cases it is unwise to use them on global variables.
当在类中引用变量时,这有一些用途,并且在某些情况下,这些变量实际上是必需的(例如在__get()、__set()、__isset()和__unset()中)。然而,在大多数情况下,在全局变量上使用它们是不明智的。
Be aware that you should NEVER directly accept end-user input when it comes to variable variables. Instead a wrapper function should be used to ensure that only specific inputs are allowed.
注意,当涉及到变量时,不应该直接接受终端用户的输入。相反,应该使用包装函数来确保只允许特定的输入。
In most cases, variable variables are not required, and it is recommended that you avoid them when possible.
在大多数情况下,不需要变量,建议尽可能避免变量。
#3
0
You can use for something like
你可以用在类似的东西上
$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>";
}
In my opinion is bad old school...
在我看来,这是糟糕的老学校……
#4
0
According to @Faiz answer (which I accepted as the formal answer to my question) I created the following sample example.
根据@Faiz的回答(我接受为我的问题的正式回答),我创建了以下示例示例。
If I had the class Customer:
如果我有班级客户:
class Customer
{
public $firstname;
public $lastname;
public $country;
public $gender;
...
}
and the web HTML form with INPUT/SELECT fields having names 'firstname','lastname','country', 'gender'...
以及带有输入/选择字段的web HTML表单,这些字段的名称有“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>
usually in my action script I would map these form fields into class variables one by one as:
通常在我的动作脚本中,我会将这些表单字段逐一映射到类变量中,如下所示:
$Customer=new Customer();
$Customer->firstname=$_POST['firstname'];
$Customer->lastname=$_POST['lastname'];
$Customer->country=$_POST['country'];
$Customer->gender=$_POST['gender'];
...
$Customer->create();
But using variable variables I can easily map all associative array values (there could be a lot of them which is error prone) into class variables using the following one line foreach loop;
但是通过使用变量变量,我可以很容易地将所有关联数组值(其中有很多是容易出错的)映射到类变量中,使用下面的一行foreach循环;
$Customer=new Customer();
foreach($_POST as $key=>$value) $Customer->$key=$value;
$Customer->create();
Note: For the sake of answer (logic) simplicity and clearness I omitted $_POST values sanitization.
注意:为了简单明了地回答(逻辑),我省略了$_POST值清理。