Имя переменной как переменная - PullRequest
1 голос
/ 21 февраля 2012

У меня есть вопрос об использовании переменных в качестве имени переменной.У меня есть массив с именами полей базы данных в качестве ключей и свойствами объекта в виде значений, подобных этому:

$properties = array("userid" => "user['userid']", "city" => "hometown");

foreach ($properties as $field => $property ) { 
  $value1 = $db->$field;
  $value2 = $obj->$property;
}

Это работает для свойства родного города, но не работает для пользователя свойства ['userid'].Как правильно адресовать переменную свойства?
Я также попробовал несколько вещей, таких как: $ {property} или {$ property}, но пока безуспешно.

edit: Спасибо за все ответы!Пока я останусь с моим оригинальным решением, мне было интересно, если был способ, у меня нет принципиальных проблем с 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};
        } 
        ....

Ответы [ 3 ]

0 голосов
/ 21 февраля 2012

, если $obj является объектом и имеет поле $property

$obj->{$property} должно работать нормально

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

$obj->{ "field_" . $field_name };

В вашем случае $property - это строка, поэтому на первой итерации она будет user['userid']

изменить: чтобы сделать его двухмерный массив $properties должны быть определены следующим образом:

$properties = array(
    'user' => array(
        'id' => 1,
        'name' => 'username'
    ),
    'city' => 'hometown'
);
0 голосов
/ 21 февраля 2012

Ваша проблема в том, что у вас есть индекс массива, и это не поддерживается синтаксисом "переменных переменных" в 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;
        }
}
0 голосов
/ 21 февраля 2012

ОК, поэтому я решил прокомментировать эту проблему. Кай (без обид :) предоставил вам решение, которое не использует eval, но за счет дополнительных 12 или около того строк кода, что делает код, несомненно, медленнее и сложнее. Так что я сам думаю, что в этом случае оправданно использовать вызов eval (). Но это может быть только я (я очень ценю четкий и короткий код).

Но будьте осторожны, если входной сигнал поступает из внешних источников , то вам следует отфильтровать его.

$properties = array("userid" => "user['userid']", "city" => "hometown");

foreach ($properties as $field => $property ) { 
  $value1 = $db->$field;
  eval("\$value2=\$obj->$property;");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...