Web

Как получить имя переменной в виде строки в PHP?

Скажем, у меня есть этот PHP-код:

$FooBar = "a string";

 

Затем мне нужна такая функция:

print_var_name($FooBar);

 

которая печатает:

FooBar

 

Любые идеи, как этого добиться? Возможно ли это вообще в PHP?

 

Ответ 1

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

get_defined_vars() в некоторых ситуациях работает некорректно, она возвращает var, потому что $var используется в самой функции.

function print_var_name($var) {

    foreach($GLOBALS as $var_name => $value) {

        if ($value === $var) {

            return $var_name;

        }

    }

    return false;

}

 

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

 

Ответ 2

Я не могу уверенно утверждать, как сделать это эффективно, но я придумал вот что. Это работает для ограниченного использования, как указано ниже.

<?php

function varName( $v ) {

    $trace = debug_backtrace();

    $vLine = file( __FILE__ );

    $fLine = $vLine[ $trace[0]['line'] - 1 ];

    preg_match( "#\\$(\w+)#", $fLine, $match );

    print_r( $match );

}

$foo = "knight";

$bar = array( 1, 2, 3 );

$baz = 12345;

varName( $foo );

varName( $bar );

varName( $baz );

?>

 

// Результат

Array (

    [0] => $foo

    [1] => foo

)

Array (

    [0] => $bar

    [1] => bar

)

Array (

    [0] => $baz

    [1] => baz

)

 

 

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

 

Ответ 3

 

Похоже, никто не упомянул основные причины, по которым это а) сложно и б) неразумно:

  • «Переменная» это просто символ, указывающий на что-то еще. В PHP она внутренне указывает на что-то, называемое «zval», которое на самом деле может использоваться для нескольких переменных одновременно либо потому, что они имеют одинаковое значение (PHP реализует то, что называется «копирование при записи», поэтому для $foo = $bar нет необходимости выделить дополнительную память сразу), либо потому, что они были назначены (или переданы функции) по ссылке (например, $foo =& $bar).

  • Когда вы передаете параметр функции, вы создаете новую переменную (даже если это ссылка). Вы можете передать что-то анонимное, например, "hello", но, оказавшись внутри вашей функции, это будет та переменная, как вы ее назовете. Это довольно фундаментально для разделения кода: если бы функция полагалась на то, как называлась переменная, она была бы больше похожа на goto, чем отдельную функцию.

  • Глобальные переменные обычно считаются плохой идеей. Многие примеры здесь предполагают, что переменная, которую вы хотите «отразить», может быть найдена в $GLOBALS, но это будет верно только в том случае, если вы плохо структурировали свой код и переменные не привязаны к какой-либо функции или объекту.

  • Имена переменных помогают программистам читать свой код. Переименование переменных в соответствии с их назначением очень распространенная практика рефакторинга, и все дело в том, что это не имеет никакого значения.

Теперь я понимаю желание использовать это для отладки (хотя некоторые из предложенных вариантов использования выходят далеко за рамки этого), но как обобщенное решение это не так полезно, как можно подумать: если ваша функция отладки говорит, что ваша переменная называется "$file", это может быть любая из десятков переменных "$file" в вашем коде, или переменная, которую вы назвали "$filename", но передаете в функцию, параметр которой называется "$file".

Гораздо более полезной информацией является то, откуда в вашем коде была вызвана функция отладки. Поскольку вы можете быстро найти это в редакторе, вы можете увидеть, какую переменную вы выводили, и даже передать в нее целые выражения за один раз (например, debug('$foo + $bar = ' . ($foo + $bar))).

 

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

$backtrace = debug_backtrace();

echo '# Debug function called from ' . $backtrace[0]['file'] . ' at line ' . $backtrace[0]['line'];

 

 

Ответ 4

Это именно то, что вам нужно,готовая к использованию функция "скопируй и вставь", которая определяет имя заданной переменной:

function print_var_name(){

    // читаем обратную трассировку

    $bt = debug_backtrace();

    // читаем файл

    $file = file($bt[0]['file']);

    // выбираем точную строку print_var_name($varname)

    $src = $file[$bt[0]['line']-1];

    // шаблон поиска

    $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';

    // извлечение $varname из совпадения №2

    $var = preg_replace($pat, '$2', $src);

    // выводим в браузер

    echo '<pre>' . trim($var) . ' = ' . print_r(current(func_get_args()), true) . '</pre>';

} 

Схожие статьи

Web

Как заставить PHP перестать заменять символы «.» в массивах $_GET или $_POST

Web

PHP REST API POSTMAN. Фатальная ошибка Uncaught PDOException: SQLSTATE[42000]: Синтаксическая ошибка или нарушение доступа: 1064 У вас ошибка в синтаксисе SQL

Сертификат SSL Let’s encrypt. Что это такое и где используется?
Web

Сертификат SSL Let’s encrypt. Что это такое и где используется?

Web

Когда я использую Plesk, отображается фатальная ошибка PHP