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

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

$FooBar = "a string";

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

print_var_name($FooBar);

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

FooBar

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

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

troelskn 01.11.2008 20:26

Для реализации точной функции для этого, вероятно, понадобится кто-то, кто взломает ядро ​​PHP. Сравнивая значения, может быть случай, когда две вары имеют одинаковое значение, поэтому это проблема. Думаю, нет "хорошего" способа сделать это.

Jimmie Lin 29.07.2010 05:43

Хороший вопрос. Мне то же нужно было для отладки.

takeshin 19.03.2011 19:00

+1 - мне это нужно для автоматического создания ответа XML или JSON от объекта PHP модели. Необходимость обернуть объект внутри другого массива с именем rootName => modelObject просто добавляет ненужной глубины ответу. Хотелось бы, чтобы это было встроено в возможности языка во время выполнения.

Anurag 17.05.2011 00:18

Мне также это было нужно в функции ведения журнала. Я хотел иметь возможность делать следующее: log ($ didTheSystemBlowUp); Чтобы появилось в файле журнала, например: $ didTheSystemBlowUp = 'еще нет, но очень скоро';

SeanDowney 23.05.2012 21:36

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

PHPst 03.12.2012 09:50

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

Damien Golding 22.04.2013 10:55

возможный дубликат Есть ли способ получить имя переменной? PHP - Отражение

user151841 04.05.2015 21:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
208
8
180 649
25
Перейти к ответу Данный вопрос помечен как решенный

Ответы 25

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

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

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

Print ("foobar") не будет обрабатывать другие вары.

Gary Willoughby 01.11.2008 03:59

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

takeshin 19.03.2011 19:03

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

b01 30.08.2012 20:13

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

Vinko Vrsalovic 31.08.2012 16:08
Ответ принят как подходящий

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

Обновлено: 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 нет хорошего способа сделать это, вероятно, потому, что вам не нужно этого делать. Вероятно, есть более эффективные способы сделать то, что вы пытаетесь сделать.

Ах. Было слишком медленно ;-) Мысль о том же, но с использованием вместо этого $ GLOBALS. Таким образом, сравнение идентичности дает истинное значение для равных скалярных значений ($ a = 'foo'; $ b = 'foo'; assert ($ a === $ b);)?

Argelbargel 01.11.2008 03:46

На самом деле теперь, когда я протестировал свой код, мой код всегда возвращал var, потому что он используется в функции. Когда я вместо этого использую $ GLOBALS, он по какой-то причине возвращает правильное имя переменной. Поэтому я изменю приведенный выше код, чтобы использовать $ GLOBALS.

Jeremy Ruten 01.11.2008 04:11

Да, я понял, но get_defined_vars () было достаточно.

Gary Willoughby 01.11.2008 04:30

Во многих случаях этот код ведет себя не так, как ожидалось.

troelskn 01.11.2008 20:25

Этот код УЖАСНО неверен. Проверять, является ли переменная такой же, как та, которую отправил VALUE, - очень глупая идея. Мириады переменных в любой момент равны NULL. Мириады установлены на 1. Это просто безумие.

Alex Weinstein 10.03.2010 08:44

Попробуйте свой код с $ a = 10; $ b = 10; print_r (print_var_name ($ b));

Ashish Rana 26.08.2017 10:12

Не будет работать, потому что существует много разных видов «переменных», имена которых было бы неплохо обнаружить: локальные переменные внутри функций, глобальные переменные, определенные константы, массивы, элементы массива, объекты, свойства класса const, статический класс. свойства, "волшебные" предопределенные константы ...

David Spector 06.10.2018 21:14

хотя это определенно не работает во многих случаях, оно ДЕЙСТВИТЕЛЬНО работает в ситуациях, когда имена переменных более подробны, что и должно отражать правильная практика кодирования. $ a и $ b - ПЛОХОЕ имена; полезно, но ПЛОХО. Я нашел эту небольшую служебную функцию чрезвычайно полезной с более подробными именами переменных и, следовательно, +1.

WhiteRau 30.03.2021 18:29

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

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

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

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

тогда ты мог бы просто

print($var_name);

получить

FooBar

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

Я работал с системой, которая широко использовала переменные переменные. Позвольте мне вас предупредить, очень быстро становится действительно вонючим!

Icode4food 14.10.2010 17:47

в большинстве случаев пользователь хочет получить имя и значение переменной. подумайте «function debugvar ($ varname)», и он намеревается назвать это «debugvar ('foo')», чтобы отладка показала «foo = 123». с переменной переменной они получат 'foo' не определено.

gcb 14.04.2011 12:01

просто посмотрите, что вы на самом деле делаете. Прямо здесь в вашем примере вы фактически СОЗДАЕТЕ переменную $FooBar со значением a string, просто прочтите свое руководство. Это ужасно имхо. вы никогда не присваиваете переменной $FooBar значение, но оно есть. ОЙ

Toskan 17.06.2014 11:47

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

пожимать плечами

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

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

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

rubo77 05.11.2013 15:56

Здесь вы найдете лучшую реализацию, которая работает с несколькими включениями: stackoverflow.com/a/19788805/1069083

rubo77 05.11.2013 16:35

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

У меня есть функция 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));
}

Но и это не удается ... :(

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

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

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

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

deceze 10.03.2010 09:09

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

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

This works fine: die(inspect($ this-> getUser () -> hasCredential ("удалить") ));

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

Получаем: $ this-> getUser () -> hasCredential ("удалить")

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

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

эээээ, разве это не зависит от того, что у вас установлен отладчик NuSphare?

Mawg says reinstate Monica 22.06.2011 07:22

Я разместил здесь упрощенную версию этого кода. Также я изменил этот ответ. Теперь он должен работать во всех реализациях PHP5.

Sebastián Grignoli 27.07.2011 03:33

Именно благодаря такой изобретательности я улыбаюсь каждый раз, когда вижу, как люди говорят «невозможно» или «невозможно», включая даже самого Расмуса в данном случае. Престижность Себастьяну и всем, кто, возможно, способствовал этому ответу.

Night Owl 03.05.2013 04:42

Спасибо, Night Owl, но я настаиваю на том, что это не пуленепробиваемое (как сказано в ответе, он потерпит неудачу, если моя функция "inspect ()" вызывается более одного раза в одной строке!). Я бы никогда не использовал это в продакшене. Это только для функции инспектора отладки, которая никогда не должна достигать производственного сервера.

Sebastián Grignoli 09.05.2013 00:15

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

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

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

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

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

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

Лукас на 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

Как получить текущую область видимости в виде массива?

Sebastián Grignoli 27.10.2010 19:18

Хороший! Мне не хватает только break;, если он найден равным в foreach +. Я сделал используемую базовую структуру, чтобы автоматически получать var_name, также если он определен внутри функции. Если вы часто копируете и вставляете или у вас есть лучшие идеи по его улучшению, используйте variable_name( $variable, ( empty(__FUNCTION__) ? false : get_defined_vars() ) );.

odie2 06.06.2015 00:12

Это, вероятно, самый быстрый и чистый способ выполнить работу, отладка, вероятно, включает проблемы с производительностью. Функция должна возвращаться непосредственно в цикле foreach, а не просто выполнять назначение без прерывания. Учитывая, что GLOBALS может быть большим, это может значительно улучшить производительность.

John 25.10.2019 19:27

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

/**
 * 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' );

От 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
?>

Вот мое решение на основе 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')
);

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

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

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

    $variableName = "ajaxmint";

    echo getVarName('$variableName');

    function getVarName($name) {
        return str_replace('$','',$name);
    }

Потому что OP не знает имени переменной. Если бы он это сделал, ему не понадобилась бы функция getVarName(). ;-)

FtDRbwLXw6 14.09.2013 01:13

Это не возвращает имя переменной в виде строки, потому что '$variableName' уже является строкой, а не переменной. Если вы можете проделать этот трюк с getVarName($variableName);, вы получите положительный голос :)

Daniel W. 17.04.2014 18:18

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

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 ; 
    }
}

@IMSoP Судя по выводам print implode( ' ', array_keys( $GLOBALS ));, это выглядит как ошибочное предположение о количестве глобальных переменных по умолчанию. В моей системе есть семь суперглобалов: $ _GET, $ _POST, $ _COOKIE, $ _FILES, $ _ENV, $ _REQUEST, $ _SERVER. Также есть argv и argc. Таким образом, смещение должно быть 9. И нет смысла указывать третий параметр (длину), поскольку по умолчанию в любом случае выполняется просто до конца массива.

Jeff 01.06.2018 00:22

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

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

$fruit='apple';
VarTest($fruit,'fruit');

Адаптировано из ответов выше для многих переменных, с хорошей производительностью, всего одно сканирование $ 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
        )

)

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

  • «Переменная» - это просто символ, указывающий на что-то еще. В 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'];

Уже есть несколько хороших ответов. Так что это просто пессимизм даже перед лицом реальности.

a20 29.06.2017 05:59

@ a20 Во всех ответах есть серьезные оговорки о том, когда их можно использовать, а когда они сломаются; none - это простой поиск любой переменной по ее имени, потому что это фактически невозможно. Некоторые делают много фанковых отражений для целей отладки, и это нормально; однако мой мнение означает, что вам лучше просто вывести номер строки и самостоятельно найти строку источника - или использовать интерактивный отладчик, такой как XDebug.

IMSoP 29.06.2017 11:51

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

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

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

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

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

Это значение переменной, а не имя переменной. Как указано в другом месте, имя не переносится за границы функций.

Owen Beresford 28.06.2014 15:22

минус один, потому что эта функция буквально ничего не делает, кроме возврата обрезки ($ var);

Alexar 18.02.2015 12:37

Для этого вы можете использовать compact ().

$FooBar = "a string";

$newArray = compact('FooBar');

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

foreach($newarray as $key => $value) {
    echo $key;
}

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

a coder 22.12.2014 18:09

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

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

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

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

Намного медленнее, чем более обычные методы объявления переменных.

David Spector 06.10.2018 21:19

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

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

HINT Now you can rename the function and it will still work and also use the function several times in one line! Thanks to @Cliffordlife

Круто, спасибо за это. Я немного изменил строку $ pat на $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i'; таким образом, мне все равно, что вызывается эта функция отладки, и я получаю именно то, что передается в функцию, то есть $ hello или "hello" (я отбросил $ match для переменной прошел в той же строке)

Cliffordlife 16.06.2016 12:21

Фантастический фрагмент кода! Спасибо! Однако не во всех случаях это работает. Результат тестирования на моем ubuntu 18.04 с php 7.2.19: не работает при многократном использовании в одной строке кода, независимо от того, используется ли он в одном или отдельных выражениях, потому что тогда он возвращает имя последней переменной линия. Если он используется в том же выражении, но в отдельных строках, он работает. Используется в разных выражениях в разных строках, это работает.

Matty 12.06.2019 10:30

также эта функция должна быть в одной строке без "var_dump" - с комбинацией print_var_name, echo, var_dump отправить вывод $variable); echo ' '; var_dump($variable

BG BRUNO 04.02.2020 16:50

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

Опция 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.");
}

Вот как я это сделал

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

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

<?php
    // Function for determining the name of a variable
    function getVarName(&$var, $definedVars=null) {
        $definedVars = (!is_array($definedVars) ? $GLOBALS : $definedVars);
        $val = $var;
        $rand = 1;
        while (in_array($rand, $definedVars, true)) {
            $rand = md5(mt_rand(10000, 1000000));
        }
        $var = $rand;
         
        foreach ($definedVars as $dvName=>$dvVal) {
            if ($dvVal === $rand) {
                $var = $val;
                return $dvName;
            }
        }
         
        return null;
    }
 
    // the name of $a is to be determined.   
    $a = 1;
     
    // Determine the name of $a
    echo getVarName($a);
?>

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

Другие вопросы по теме