Есть ли способ получить имя переменной? PHP - отражение

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

Конечно, когда программист пишет вызов функции, они уже знают имя переменной, поэтому они могут написать что-то вроде:

debug( $myvar, 'myvar' );

Но я хочу, чтобы это было быстро и легко писать, просто имя функции, переменную и voilà!

debug( $myvar ); // quicker and easier :)

Ответ 1

Вы можете сделать это, преобразов переменную в набор ключей/значений перед передачей ее функции.

function varName($theVar) {  
   $variableName = key($theVar);  
   $variableValue = $theVar[$variableName];  
   echo ('The name of the variable used in the function call was '.$variableName.'<br />');  
   echo ('The value of the variable used in the function call was '.$variableValue.'<br />');  
}
$myVar = 'abc';
varName(compact('myVar'));

Хотя я не рекомендую создавать ссылку на безымянную переменную, function varName(&$theVar) тоже работает.

Так как compact() принимает имя переменной как строку, а не фактическую переменную, итерация по списку имен переменных должна быть простой.

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

Ответ 2

Я знаю, что отвечаю на 4-летний вопрос, но какого черта...

compact() может помочь вам, ваш друг здесь!

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

function vlog() {
    $args = func_get_args();
    foreach ($args as $arg) {
        global ${$arg};
    }
    return json_encode(compact($args));
}

Я обнаружил, что JSON является самой чистой и наиболее читаемой формой для этих дампов для моих журналов, но вы также можете использовать что-то вроде print_r() или var_export().

Вот как я его использую:

$foo = 'Elvis';
$bar = 42;
$obj = new SomeFancyObject();

log('Something went wrong! vars='.vlog('foo', 'bar', 'obj'));

И это будет печататься следующим образом в журналах:

Что-то пошло не так! vars = { "foo": "Elvis", "bar": 42, "obj": { "nestedProperty1": 1, "nestedProperty2": "etc." }}

Слово предупреждения: это будет работать только для переменных, объявленных в глобальной области (так что не внутри функций или классов). Там вам нужно вызвать compact() напрямую, чтобы он имел доступ к этой области, но это не так, большой объем сделки, так как этот vlog() в основном является ярлыком для json_encode (compact ('foo', 'bar', 'obj')), сохраняя мне 16 нажатий клавиш каждый раз, когда мне это нужно.

Ответ 3

Нет, это невозможно. К сожалению.

Ответ 4

Нет, тем ближе вы получите get_defined_vars().

EDIT: я был не прав, прочитав комментарии пользователя на get_defined_vars(), это возможно с небольшим взломом:

function ev($variable){
    foreach($GLOBALS as $key => $value){
        if($variable===$value){
            echo '<p>$'.$key.' - '.$value.'</p>';
        }
    }
}

$lol = 123;

ev($lol); // $lol - 123

Работает только с уникальным содержимым переменной.

Ответ 5

У меня была такая же мысль раньше, но если вы действительно думаете об этом, вы поймете, почему это невозможно... предположительно ваша функция debug будет определяться следующим образом: function debug($someVar) { }, и нет никакого способа для он должен знать, что исходная переменная называлась $myvar.

Абсолютно лучшее, что вы могли бы сделать, это посмотреть на что-то вроде get_defined_vars() или $_GLOBALS (если оно было глобальным по какой-то причине) и пропустить это, чтобы найти что-то, что соответствует значению вашей переменной. Это очень хакерский и не очень надежный метод. Ваш оригинальный метод является наиболее эффективным способом.

Ответ 6

Не изящно... НО ВЫ МОЖЕТЕ ПОЛУЧИТЬ ЭТО!

  • 1) Пейте достаточно, чтобы убедить себя, что это хорошая идея (это займет много времени).
  • 2) Замените все переменные переменными:
$a = 10
//becomes
$a = '0a';
$$a = 10;
  • 3) Ссылка $$ a во всем вашем коде.
  • 4) Когда вам нужно распечатать переменную, напечатайте $a и разделите ведущее 0.

Приложение: делайте это только в том случае, если вы

  • Никогда не показывать этот код кому-либо
  • Никогда не нужно изменять или поддерживать этот код.
  • Сумасшедшие
  • Не делать этого для работы
  • Посмотрите, просто никогда не делайте этого, это шутка.

Ответ 8

Вы можете использовать eval:

function debug($variablename)
{
  echo ($variablename . ":<br/>");
  eval("global $". $variablename . ";");
  eval("var_dump($" . $variablename . ");");
}

Использование: debug("myvar") not debug($myvar)

Ответ 9

Я считаю, что Alix и nickf предлагают это:

function debug($variablename)
{
  echo ($variablename . ":<br/>");
  global $$variablename; // enable scope
  var_dump($$variablename);
}

Я тестировал его и, похоже, работал так же хорошо, как и код Wagger (Спасибо Wagger: Я столько раз пытался прочесть это, и объявление глобальной переменной было моим камнем преткновения)

Ответ 10

Это поздний пост, но я думаю, что теперь можно использовать метод compact

поэтому код будет

$a=1;
$b=2;
$c=3

var_dump(compact('a','b','c'));

выход будет

array (size=3)
'a' => int 1
'b' => int 2
'c' => int 3

где переменные name a, b и c являются ключевыми

Надеюсь, что это поможет