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

201

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

$FooBar = "a string";

тогда мне нужна такая функция:

print_var_name($FooBar);

который печатает:

FooBar

Есть идеи как этого добиться? Это вообще возможно в PHP?

Гари Уиллоуби
источник
9
Если вам нужно что-то кроме отладки, вы делаете что-то строго неправильно. Какой у вас сценарий использования?
troelskn
10
Хороший вопрос. Мне нужно то же самое для отладки.
принимает
17
+1 - мне это нужно для автоматической генерации ответа XML или JSON из модельного объекта PHP. Необходимость обернуть объект в другой именованный rootName => modelObjectмассив просто добавляет ненужную глубину в ответ. Хотелось бы, чтобы это было включено в возможности отражения во время выполнения языка.
Анураг
4
Я также нуждался в этом в функции регистрации. Я хотел иметь возможность сделать следующее: log ($ didTheSystemBlowUp); Для отображения в файле журнала, например: $ didTheSystemBlowUp = 'пока нет, но очень скоро';
SeanDowney
4
Также это может быть полезно при вызове var_dump (), поэтому, когда вы вызываете одновременно несколько переменных, вы не выводите имя var вручную, чтобы различать выходные данные vardupms.
PHPst

Ответы:

37

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

Edit: get_defined_vars (), кажется, не работает правильно, он возвращает 'var', потому что $ var используется в самой функции. $ GLOBALS, кажется, работает, поэтому я изменил его на это.

function print_var_name($var) {
    foreach($GLOBALS as $var_name => $value) {
        if ($value === $var) {
            return $var_name;
        }
    }

    return false;
}

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

Джереми Рутен
источник
2
Ааа. Замедлился ;-) Мысль та же, но вместо нее используется $ GLOBALS. Таким образом, сравнение тождества дает true для равных скалярных значений ($ a = 'foo'; $ b = 'foo'; assert ($ a === $ b);)?
Argelbargel
На самом деле теперь, когда я протестировал свой код, мой код всегда возвращал 'var', потому что он используется в функции. Когда я вместо этого использую $ GLOBALS, он по какой-то причине возвращает правильное имя переменной. Поэтому я изменю приведенный выше код на использование $ GLOBALS.
Джереми Рутен
Да, я понял, но get_defined_vars () было достаточно.
Гари Уиллоуби
2
Есть много случаев, когда этот код будет работать не так, как ожидалось.
troelskn
122
Этот код УЖАСНО неверен. Проверять, чтобы увидеть, что переменная такая же, как и та, что была передана VALUE, очень глупая идея. Множество переменных равны NULL в любой заданной точке. Мириады установлены в 1. Это просто безумие.
Алекс Вайнштейн
49

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

пожимание плечами

<?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 );

?>

// Returns
Array
(
    [0] => $foo
    [1] => foo
)
Array
(
    [0] => $bar
    [1] => bar
)
Array
(
    [0] => $baz
    [1] => baz
)

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

Ник преста
источник
2
Это работает, но только если функция varName определена в том же файле, что и переменная, которую нужно найти.
rubo77
1
Здесь вы найдете лучшую реализацию, которая работает в нескольких направлениях: stackoverflow.com/a/19788805/1069083
rubo77
31

Вы могли бы подумать об изменении вашего подхода и использовании имени переменной переменной?

$var_name = "FooBar";
$$var_name = "a string";

тогда вы могли бы просто

print($var_name);

получить

FooBar

Вот ссылка на руководство PHP по переменным переменным


источник
42
Я работал с системой, которая широко использовала переменные переменные. Позвольте мне предупредить вас, это становится очень вонючим, очень быстро!
Icode4food
3
В большинстве случаев пользователь хочет получить имя и значение переменной. подумайте «функция debugvar ($ varname)», и он намеревается назвать ее «debugvar ('foo')», поэтому отладка покажет «foo = 123». с переменной переменной они получат 'foo' не определено.
gcb
просто посмотрите, что вы на самом деле делаете. Прямо в вашем примере вы фактически СОЗДАЕТЕ переменную $FooBarсо значением, a stringпросто прочитав ваше руководство. Это ужасно, имхо. Вы никогда не назначаете переменной $FooBarзначение, но оно есть. OUCH
Toskan
20

Кажется, никто не упомянул фундаментальные причины, почему это а) сложно и б) неразумно:

  • «Переменная» - это просто символ, указывающий на что-то еще. В 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'];
IMSoP
источник
Уже есть несколько хороших ответов. Так что это просто пессимистично даже перед лицом реальности.
20
@ a20 Все ответы содержат серьезные замечания о том, когда их можно использовать и когда они сломаются; нет простого поиска любой переменной по ее имени, потому что это на самом деле невозможно. Некоторые из них делают много лишних размышлений для целей отладки, и это нормально; Тем не менее, я считаю, что вам лучше просто вывести номер строки и посмотреть строку исходного кода самостоятельно - или использовать интерактивный отладчик, такой как XDebug.
IMSoP
14

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

function print_var_name(){
    // read backtrace
    $bt   = debug_backtrace();
    // read file
    $file = file($bt[0]['file']);
    // select exact print_var_name($varname) line
    $src  = $file[$bt[0]['line']-1];
    // search pattern
    $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';
    // extract $varname from match no 2
    $var  = preg_replace($pat, '$2', $src);
    // print to browser
    echo trim($var);
}

ИСПОЛЬЗОВАНИЕ: print_var_name ($ FooBar)

ПЕЧАТЬ: FooBar

СОВЕТ Теперь вы можете переименовать функцию, и она все равно будет работать, а также использовать функцию несколько раз в одной строке! Благодаря @ Cliffordlife

adilbo
источник
3
Круто, спасибо за это. Я немного изменил строку $ pat $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';таким образом, что мне все равно, как называется эта функция отладки, и я получаю именно то, что передается в функцию, например, $ hello или "hello" (я отбросил $ match для переданной переменной в, в той же строке)
Cliffordlife
1
Фантастический кусок кода! Спасибо! Однако, похоже, что это не работает во всех случаях. Результат тестирования на моем Ubuntu 18.04 с php 7.2.19: не работает при многократном использовании в одной и той же строке кода, независимо от того, используется ли он в одном или отдельных выражениях, потому что тогда он возвращает имя последней переменной линия. Если он используется в том же выражении, но в отдельных строках, он работает. Используется в разных выражениях, в разных строках это работает.
Мэтти
1
также эта функция должна быть в одной строке без "var_dump" - с комбинированным print_var_name, echo, var_dumpвыводом$variable); echo ' '; var_dump($variable
BG Bruno
13

Lucas на PHP.net предоставил надежный способ проверить, существует ли переменная. В своем примере он перебирает копию массива глобальных переменных (или области видимости) переменных, изменяет значение на случайно сгенерированное значение и проверяет сгенерированное значение в скопированном массиве.

function variable_name( &$var, $scope=false, $prefix='UNIQUE', $suffix='VARIABLE' ){
    if($scope) {
        $vals = $scope;
    } else {
        $vals = $GLOBALS;
    }
    $old = $var;
    $var = $new = $prefix.rand().$suffix;
    $vname = FALSE;
    foreach($vals as $key => $val) {
        if($val === $new) $vname = $key;
    }
    $var = $old;
    return $vname;
}

Тогда попробуйте:

$a = 'asdf';
$b = 'asdf';
$c = FALSE;
$d = FALSE;

echo variable_name($a); // a
echo variable_name($b); // b
echo variable_name($c); // c
echo variable_name($d); // d

Обязательно ознакомьтесь с его постом на PHP.net: http://php.net/manual/en/language.variables.php

мастеровой
источник
Как вы получаете текущую область в виде массива?
Себастьян Гриньоли
Ницца! Для меня пропущено только то, break;что было найдено равным в foreach + я применил базовую структуру, чтобы автоматически получить var_name, даже если он определен внутри функции. Если вы часто variable_name( $variable, ( empty(__FUNCTION__) ? false : get_defined_vars() ) );
копируете и вставляете
Это, вероятно, самый быстрый и чистый способ выполнения работы, отладка, вероятно, включает проблемы с производительностью. Функция должна возвращаться непосредственно в цикл foreach, а не просто назначать без прерывания. Учитывая, что GLOBALS могут быть большими, это может значительно улучшить производительность.
Джон
13

Я сделал функцию проверки по причинам отладки. Это похоже на print_r () на стероидах, очень похоже на Krumo, но немного более эффективно на объектах. Я хотел добавить определение имени var и получил это, вдохновленный постом Ника Престы на этой странице. Он обнаруживает любое выражение, переданное в качестве аргумента, а не только имена переменных.

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

Это отлично работает: die ( осмотреть ($ This-> GetUser () -> hasCredential ( "Удалить")) );

inspect () - это функция, которая обнаружит переданное выражение.

Мы получаем: $ this-> getUser () -> hasCredential ("delete")

function inspect($label, $value = "__undefin_e_d__")
{
    if($value == "__undefin_e_d__") {

        /* The first argument is not the label but the 
           variable to inspect itself, so we need a label.
           Let's try to find out it's name by peeking at 
           the source code. 
        */

        /* The reason for using an exotic string like 
           "__undefin_e_d__" instead of NULL here is that 
           inspected variables can also be NULL and I want 
           to inspect them anyway.
        */

        $value = $label;

        $bt = debug_backtrace();
        $src = file($bt[0]["file"]);
        $line = $src[ $bt[0]['line'] - 1 ];

        // let's match the function call and the last closing bracket
        preg_match( "#inspect\((.+)\)#", $line, $match );

        /* let's count brackets to see how many of them actually belongs 
           to the var name
           Eg:   die(inspect($this->getUser()->hasCredential("delete")));
                  We want:   $this->getUser()->hasCredential("delete")
        */
        $max = strlen($match[1]);
        $varname = "";
        $c = 0;
        for($i = 0; $i < $max; $i++){
            if(     $match[1]{$i} == "(" ) $c++;
            elseif( $match[1]{$i} == ")" ) $c--;
            if($c < 0) break;
            $varname .=  $match[1]{$i};
        }
        $label = $varname;
    }

    // $label now holds the name of the passed variable ($ included)
    // Eg:   inspect($hello) 
    //             => $label = "$hello"
    // or the whole expression evaluated
    // Eg:   inspect($this->getUser()->hasCredential("delete"))
    //             => $label = "$this->getUser()->hasCredential(\"delete\")"

    // now the actual function call to the inspector method, 
    // passing the var name as the label:

      // return dInspect::dump($label, $val);
         // UPDATE: I commented this line because people got confused about 
         // the dInspect class, wich has nothing to do with the issue here.

    echo("The label is: ".$label);
    echo("The value is: ".$value);

}

Вот пример функции инспектора (и моего класса dInspect) в действии:

http://inspect.ip1.cc

Тексты на этой странице на испанском, но код лаконичен и действительно прост для понимания.

Себастьян Гриньоли
источник
1
э-э, разве это не зависит от того, что у вас установлен отладчик NuSphare?
Mawg говорит восстановить Monica
Я разместил там упрощенную версию этого кода. Также я изменил этот ответ. Теперь он должен работать на каждой реализации PHP5.
Себастьян Гриньоли
Подобная изобретательность, вот почему я улыбаюсь каждый раз, когда вижу, что люди говорят «невозможно» или «невозможно», в том числе даже сам Расмус. Престижность Себастьяну и всем, кто мог поспособствовать этому ответу.
Ночная сова
1
Спасибо Night Owl, но я настаиваю на том, что это не является пуленепробиваемым (как говорится в ответе, произойдет сбой, если моя функция «inspect ()» будет вызываться более одного раза в одной строке!). Я бы никогда не использовал это в производстве. Это только для функции инспектора отладки, которая никогда не должна достигать рабочего сервера.
Себастьян Гриньоли,
7

С php.net

@Alexandre - короткое решение

<?php
function vname(&$var, $scope=0)
{
    $old = $var;
    if (($key = array_search($var = 'unique'.rand().'value', !$scope ? $GLOBALS : $scope)) && $var = $old) return $key;  
}
?>

@Lucas - использование

<?php
//1.  Use of a variable contained in the global scope (default):
  $my_global_variable = "My global string.";
  echo vname($my_global_variable); // Outputs:  my_global_variable

//2.  Use of a local variable:
  function my_local_func()
  {
    $my_local_variable = "My local string.";
    return vname($my_local_variable, get_defined_vars());
  }
  echo my_local_func(); // Outputs: my_local_variable

//3.  Use of an object property:
  class myclass
  {
    public function __constructor()
    {
      $this->my_object_property = "My object property  string.";
    }
  }
  $obj = new myclass;
  echo vname($obj->my_object_property, $obj); // Outputs: my_object_property
?>

источник
4

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

function getReference(&$var)
{
    if(is_object($var))
        $var->___uniqid = uniqid();
    else
        $var = serialize($var);
    $name = getReference_traverse($var,$GLOBALS);
    if(is_object($var))
        unset($var->___uniqid);
    else
        $var = unserialize($var);
    return "\${$name}";    
}

function getReference_traverse(&$var,$arr)
{
    if($name = array_search($var,$arr,true))
        return "{$name}";
    foreach($arr as $key=>$value)
        if(is_object($value))
            if($name = getReference_traverse($var,get_object_vars($value)))
                return "{$key}->{$name}";
}

Пример для вышесказанного:

class A
{
    public function whatIs()
    {
        echo getReference($this);
    }
}

$B = 12;
$C = 12;
$D = new A;

echo getReference($B)."<br/>"; //$B
echo getReference($C)."<br/>"; //$C
$D->whatIs(); //$D
К. Бруннер
источник
2

Адаптировано из ответов выше для многих переменных, с хорошей производительностью, всего один просмотр $ GLOBALS для многих

function compact_assoc(&$v1='__undefined__', &$v2='__undefined__',&$v3='__undefined__',&$v4='__undefined__',&$v5='__undefined__',&$v6='__undefined__',&$v7='__undefined__',&$v8='__undefined__',&$v9='__undefined__',&$v10='__undefined__',&$v11='__undefined__',&$v12='__undefined__',&$v13='__undefined__',&$v14='__undefined__',&$v15='__undefined__',&$v16='__undefined__',&$v17='__undefined__',&$v18='__undefined__',&$v19='__undefined__'
) {
    $defined_vars=get_defined_vars();

    $result=Array();
    $reverse_key=Array();
    $original_value=Array();
    foreach( $defined_vars as $source_key => $source_value){
        if($source_value==='__undefined__') break;
        $original_value[$source_key]=$$source_key;
        $new_test_value="PREFIX".rand()."SUFIX";
        $reverse_key[$new_test_value]=$source_key;
        $$source_key=$new_test_value;

    }
    foreach($GLOBALS as $key => &$value){
        if( is_string($value) && isset($reverse_key[$value])  ) {
            $result[$key]=&$value;
        }
    }
    foreach( $original_value as $source_key => $original_value){
        $$source_key=$original_value;
    }
    return $result;
}


$a = 'A';
$b = 'B';
$c = '999';
$myArray=Array ('id'=>'id123','name'=>'Foo');
print_r(compact_assoc($a,$b,$c,$myArray) );

//print
Array
(
    [a] => A
    [b] => B
    [c] => 999
    [myArray] => Array
        (
            [id] => id123
            [name] => Foo
        )

)
user1933288
источник
1

Если переменная взаимозаменяемы, вы должны иметь логику где - то , что это определяющее , какую переменный привыкает. Все, что вам нужно сделать, это поместить имя переменной в$variable эту логику, пока вы делаете все остальное.

Я думаю, что нам всем трудно понять, зачем тебе это нужно. Пример кода или объяснение того, что вы на самом деле пытаетесь сделать, может помочь, но я подозреваю, что вы, путь overthinking это.

ceejayoz
источник
1

У меня есть действительный вариант использования для этого.

У меня есть функция cacheVariable ($ var) (хорошо, у меня есть кэш функции ($ key, $ value), но я хотел бы иметь функцию, как уже упоминалось).

Цель состоит в том, чтобы сделать:

$colour = 'blue';
cacheVariable($colour);

...

// another session

...

$myColour = getCachedVariable('colour');

Я пробовал с

function cacheVariable($variable) {
   $key = ${$variable}; // This doesn't help! It only gives 'variable'.
   // do some caching using suitable backend such as apc, memcache or ramdisk
}

Я также пытался с

function varName(&$var) {
   $definedVariables = get_defined_vars();
   $copyOfDefinedVariables = array();
   foreach ($definedVariables as $variable=>$value) {
      $copyOfDefinedVariables[$variable] = $value;
   }
   $oldVar = $var;
   $var = !$var;
   $difference = array_diff_assoc($definedVariables, $copyOfDefinedVariables);
   $var = $oldVar;
   return key(array_slice($difference, 0, 1, true));
}

Но и это не помогает ... :(

Конечно, я мог бы продолжать делать кеш ('color', $ color), но я ленивый, вы знаете ...;)

Итак, мне нужна функция, которая получает ОРИГИНАЛЬНОЕ имя переменной, как оно было передано функции. Внутри функции я никак не могу это знать, как кажется. Передача get_defined_vars () по ссылке во втором примере выше мне очень помогла (спасибо Жан-Жаку Гугану за эту идею). Последняя функция начала работать, но она все еще продолжала возвращать локальную переменную («переменная», а не «цвет»).

Я еще не пробовал использовать get_func_args () и get_func_arg (), $ {} - конструкции и key () вместе, но я полагаю, что это тоже не удастся.

Арон Седерхольм
источник
1
Самая основная проблема заключается в том, что вы передаете значения в функции, а не переменные . Переменные носят временный характер и зависят от их объема. Часто имя переменной не может быть ключом, в котором вы хотите кэшировать значение, и часто вы все равно восстанавливаете его в переменную с другим именем (как вы делаете в своем примере). Если вам действительно лень повторять имя ключа, чтобы запомнить переменную, используйте cacheVariable(compact('color')).
deceze
1

У меня есть это:

  debug_echo(array('$query'=>$query, '$nrUsers'=>$nrUsers, '$hdr'=>$hdr));

Я бы предпочел это:

  debug_echo($query, $nrUsers, $hdr);

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

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

Уилл Фасти
источник
1

Вот мое решение, основанное на Jeremy Ruten

class DebugHelper {

    function printVarNames($systemDefinedVars, $varNames) {
        foreach ($systemDefinedVars as $var=>$value) {
            if (in_array($var, $varNames )) {
                var_dump($var);
                var_dump($value);
            }
        }
    }
}

используй это

DebugHelper::printVarNames(
    $systemDefinedVars = get_defined_vars(),
    $varNames=array('yourVar00', 'yourVar01')
);
dakiquang
источник
0

Почему бы вам просто не построить простую функцию и НЕ СКАЗАТЬ?

/**
 * Prints out $obj for debug
 *
 * @param any_type $obj
 * @param (string) $title
 */
function print_all( $obj, $title = false )
{
    print "\n<div style=\"font-family:Arial;\">\n";
    if( $title ) print "<div style=\"background-color:red; color:white; font-size:16px; font-weight:bold; margin:0; padding:10px; text-align:center;\">$title</div>\n";
    print "<pre style=\"background-color:yellow; border:2px solid red; color:black; margin:0; padding:10px;\">\n\n";
    var_export( $obj );
    print "\n\n</pre>\n</div>\n";
}

print_all( $aUser, '$aUser' );
Старик
источник
0

Я искал это, но просто решил ввести имя, у меня все равно обычно есть имя в буфере обмена.

function VarTest($my_var,$my_var_name){
    echo '$'.$my_var_name.': '.$my_var.'<br />';
}

$fruit='apple';
VarTest($fruit,'fruit');
Кирон Акстен
источник
0

Вы можете использовать compact () для достижения этой цели.

$FooBar = "a string";

$newArray = compact('FooBar');

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

foreach($newarray as $key => $value) {
    echo $key;
}
Budove
источник
2
Круто, но вы должны знать имя переменной, чтобы использовать ее. ОП ищет программно определить имя переменной.
кодер
0

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

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

$vars = array('FooBar' => 'a string');

Когда вы хотите получить имена переменных, используйте array_keys($vars), он вернет массив тех имен переменных, которые использовались в вашем $varsмассиве в качестве ключей.

Джанака Р Раджапакша
источник
Гораздо медленнее, чем обычные методы объявления переменных.
Дэвид Спектор
0

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

Опция 1:

$data = array('$FooBar');  

$vars = [];  
$vars = preg_replace('/^\\$/', '', $data); 

$varname = key(compact($vars));  
echo $varname;

Печать:

FooBar

По какой-то причине вы окажетесь в такой ситуации, это действительно работает.

,
Вариант 2:

$FooBar = "a string";  

$varname = trim(array_search($FooBar, $GLOBALS), " \t.");  
echo $varname;

Если $FooBarсодержит уникальное значение, он выведет «FooBar». Если $FooBarпусто или равно нулю, будет напечатано имя первой найденной пустой или нулевой строки.

Это может быть использовано как таковое:

if (isset($FooBar) && !is_null($FooBar) && !empty($FooBar)) {
    $FooBar = "a string";
    $varname = trim(array_search($FooBar, $GLOBALS), " \t.");
}
Stuperfied
источник
0

Я так и сделал

function getVar(&$var) {
    $tmp = $var; // store the variable value
    $var = '_$_%&33xc$%^*7_r4'; // give the variable a new unique value
    $name = array_search($var, $GLOBALS); // search $GLOBALS for that unique value and return the key(variable)
    $var = $tmp; // restore the variable old value
    return $name;
}

использование

$city  = "San Francisco";
echo getVar($city); // city

Примечание: некоторые PHP 7 версии не будет работать должным образом из - за ошибки в array_searchс $GLOBALS, однако все остальные версии будут работать.

Смотрите это https://3v4l.org/UMW7V

дождь
источник
-1

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

function get_user_var_defined () 
{
    return array_slice($GLOBALS,8,count($GLOBALS)-8);     
}

function get_var_name ($var) 
{
    $vuser = get_user_var_defined(); 
    foreach($vuser as $key=>$value) 
    {
        if($var===$value) return $key ; 
    }
}
user1446000
источник
@IMSoP Судя по выходным данным, print implode( ' ', array_keys( $GLOBALS ));это выглядит как ошибочное предположение о количестве глобальных переменных «по умолчанию». В моей системе есть семь суперглобалов: $ _GET, $ _POST, $ _COOKIE, $ _FILES, $ _ENV, $ _REQUEST, $ _SERVER. И есть также argv и argc. Таким образом, смещение должно быть 9. И нет смысла указывать третий параметр (длину), так как по умолчанию в любом случае просто запуск до конца массива.
Джефф
-2

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

public function getVarName($var) {      
  $tmp = array($var => '');
  $keys = array_keys($tmp);
  return trim($keys[0]);
}

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

затем мы получаем значение этого ключа с помощью array_keys и возвращаем его.

очевидно, что это быстро запутывается и нежелательно в производственной среде, но это работает для представленной проблемы.

user3344253
источник
1
Это значение переменной, а не имя переменной. Как указано в другом месте, имя не переносится через границы функций.
Оуэн Бересфорд
3
минус один, потому что эта функция в буквальном смысле ничего не делает, но возвращает обрезку ($ var);
Алексар
-3

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

    $variableName = "ajaxmint";

    echo getVarName('$variableName');

    function getVarName($name) {
        return str_replace('$','',$name);
    }
Ajaxmint
источник
6
Потому что ОП не знает имя переменной. Если он это сделает, ему не понадобится getVarName()функция. ;-)
FtDRbwLXw6
1
Это не возвращает имя переменной в виде строки, потому что '$variableName'это уже строка, а не переменная. Если вы можете сделать этот трюк с getVarName($variableName);, вы получите upvote :)
Даниэль W.
-4

Я действительно не вижу варианта использования ... Если вы введете print_var_name ($ foobar), что такого сложного (и другого) в наборе print ("foobar")?

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

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

Винко Врсалович
источник
Print ("foobar") не будет обрабатывать другие переменные.
Гари Уиллоуби
7
Вариант использования: у вас есть несколько точек отладки в коде, возвращающем одно и то же значение. Как узнать, какой из них был казнен первым? Печать этикетки очень полезна.
занимает
Тогда вы не сделали достаточно программирования. У большинства языков, с которыми я сталкивался, есть некоторый способ сделать это, обычно простой.
b01
@ b01 Я много сделал. Я прекрасно знаю, что есть много языков, которые позволяют это, но это само по себе ничего не значит. Многие языки предлагают какой-либо способ легко выполнить goto, и это не означает, что вы должны использовать его, чтобы избежать написания правильного управления потоком. Это похожий случай на мой взгляд. Я не сомневаюсь, что есть оправданные случаи, и именно поэтому я задавался вопросом о правильных случаях его использования.
Винко Врсалович