У меня вопрос об использовании переменных как variablename. У меня есть массив с именами полей базы данных в качестве свойств ключа и объекта в качестве таких значений:
$properties = array("userid" => "user['userid']", "city" => "hometown"); foreach ($properties as $field => $property ) { $value1 = $db->$field; $value2 = $obj->$property; }
Это работает для родного города собственности, но не работает для пользователя свойства ['userid']. Каков правильный способ обращения к переменной свойств?
Я также пробовал несколько вещей, таких как: $ {property} или {$ property}, но пока не повезло.
Редактировать: Спасибо за все ответы! Пока я останусь с моим оригинальным решением, мне было интересно, есть ли способ, у меня нет принципиальных проблем с версией eval, помните об этом!
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}; } ....
Хорошо, поэтому я решил прокомментировать эту проблему. Кай (без обид 🙂 предоставил вам решение, которое не использует eval, но за счет дополнительных 12 или около того строк кода, делая код без сомнения более медленным и более сложным. Поэтому я сам думаю, что в этом случае оправданно использовать вызов eval (). Hovewer, это может быть только я (я очень ценю четкий и короткий код).
Но будьте осторожны, если вход поступает из внешних источников , тогда вы должны его фильтровать.
$properties = array("userid" => "user['userid']", "city" => "hometown"); foreach ($properties as $field => $property ) { $value1 = $db->$field; eval("\$value2=\$obj->$property;"); }
если $obj
– объект и имеет $property
поля $property
$obj->{$property}
должно работать нормально
также вы можете использовать фигурные скобки с конкатенированными строками типа:
$obj->{ "field_" . $field_name };
В вашем случае $property
является строкой, поэтому на первой итерации будет user['userid']
edit: чтобы сделать его 2-мерным массивом $properties
, нужно определить следующим образом:
$properties = array( 'user' => array( 'id' => 1, 'name' => 'username' ), 'city' => 'hometown' );
Ваша проблема в том, что у вас есть индекс массива, и это не поддерживается синтаксисом «переменных переменных» PHP.
Я знаю, что это своего рода магия, но вы можете сделать это без использования зла eval()
.
Обратите внимание: это просто доказательство концепции, чтобы показать, что это возможно.
То, что вам действительно нужно, реорганизует ваш код таким образом, чтобы такой взлом не был необходим .
$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; } }