可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a question about using variables as variablename. I have an array with database fieldnames as key and object properties as values like this:
$properties = array("userid" => "user['userid']", "city" => "hometown"); foreach ($properties as $field => $property ) { $value1 = $db->$field; $value2 = $obj->$property; }
This works for the property hometown but doesn't work voor de property user['userid']. What is the correct way to adress the property variable?
I also tried several things like: ${property} or {$property} but without luck yet.
edit: Thanks for all the responses! For now I'll stay with my original solution, I was wondering if there was a way, I don't have principal problems with the eval version, will keep it in mind!
foreach ($fields as $field => $property ) { switch ($field) { case "userid": $newvalue = $this->user['userid']; $oldvalue = $original->user['userid']; break; // more cases ... default: $newvalue = $this->{$property}; $oldvalue = $original->($property}; } ....
回答1:
OK, so I decided to comment on this problem. Kai (no offence :) provided you a solution which doesn't use eval, but at the cost of additional 12 or so lines of code, making the code no doubt slower and more complex. So I myself think that in this case, it is justified to use eval() call. Hovewer, that could be just me (I value clear and short code a lot).
But beware, if input is coming from external sources, then you should filter it.
$properties = array("userid" => "user['userid']", "city" => "hometown"); foreach ($properties as $field => $property ) { $value1 = $db->$field; eval("\$value2=\$obj->$property;"); }
回答2:
if $obj
is an object and has a field $property
$obj->{$property}
should be working fine
also you can use the curly brackets with concatenated strings like:
$obj->{ "field_" . $field_name };
In your case $property
is a string, so on the first iteration it will be user['userid']
edit: to make it 2 dimensional array $properties
have to be defined like this:
$properties = array( 'user' => array( 'id' => 1, 'name' => 'username' ), 'city' => 'hometown' );
回答3:
Your problem is that you have an array index there and this is not supported by the "variable variables" syntax of PHP.
I know this is kind of magic, but you can do this without the use of evil eval()
.
Please note: this is just a proof of concept to show that it's possible.
What you really should to is refactor your code in a way so that such a hack is not necessary.
$bar = "hallo"; $foo['bar']['baz'] = "hallo2"; $properties = array('bar', "foo['bar']['baz']"); // DOES NOT WORK foreach ($properties as $property) echo "$property = ", $$property, "\n"; /* Results in: * bar = hallo * foo['bar']['baz'] = PHP Notice: Undefined variable: foo['bar']['baz'] in /tmp/test.php on line 8 */ // DOES WORK foreach ($properties as $property) echo "$property = ", get_var($property), "\n"; /* Results in: * bar = hallo * foo['bar']['baz'] = hallo2 */ // dark magic starts here function get_var($name) { if (strpos($name, '[') === false) { global $$name; return $$name; } else { // split variable name into array name and nested index segments preg_match_all("#[^\[\]\"']+#", $name, $parts); $parts = $parts[0]; // get pointer to array and walk down to the desired (nested) index $varname = array_shift($parts); global $$varname; $pointer =& $$varname; foreach ($parts as $index) { $pointer =& $pointer[$index]; } return $pointer; } }