Як отримати ім'я змінної у вигляді рядка в 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 (), щоб знайти ім'я змінної, яка має те саме значення, що і те, для якого ви намагаєтесь знайти ім'я. Очевидно, це не завжди спрацює, оскільки різні змінні часто мають однакові значення, але це єдиний спосіб, коли я можу це зробити.

Редагувати: 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. Отже порівняння ідентичності відповідає істинним скалярним значенням ($ 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
у більшості випадків користувач хоче отримати ім'я та значення var. подумайте "функція налагодження ($ varname)", і він має намір назвати це "debugvar ('foo") ", тому налагодження покаже" foo = 123 ". зі змінною змінною вони отримають 'foo' не визначено.
gcb

просто подивіться, що ви насправді робите. Тут же у вашому прикладі ви СТВОРИТИ змінну $FooBarзі значенням, a stringщойно прочитане вашим посібником. Це жахливо імхо. ви ніколи не присвоюєте змінній $FooBarзначення, але воно є. АЙ
Toskan

20

Здається, ніхто не згадував основних причин, чому це а) важко і б) нерозумно:

  • "Змінна" - це просто символ, що вказує на щось інше. У PHP вона внутрішньо вказує на щось, що називається "zval", яке насправді може використовуватися для декількох змінних одночасно, або тому, що вони мають однакове значення (PHP реалізує щось, що називається "копіювати на запис", так що $foo = $barне потрібно виділити додаткову пам'ять відразу) або тому, що вони були призначені (або передані функції) за посиланням (наприклад $foo =& $bar). Тож zval не має імені.
  • Коли ви передаєте параметр функції, ви створюєте нову змінну (навіть якщо це посилання). Ви можете передати щось анонімне, як-от "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

@ a20 У всіх відповідях є важкі застереження щодо того, коли їх можна використовувати і коли вони будуть ламатися; жоден не є простим пошуком будь-якої змінної на її ім'я, тому що це насправді неможливо. Деякі роблять багато прикольних роздумів для налагодження, що добре; однак, на мою думку , вам краще просто вивести номер рядка і самостійно шукати рядок джерела - або використовувати інтерактивний налагоджувач, як XDebug.
IMSoP

14

Це саме те, що ви хочете - це готова до використання функція "копіювати і скидати", що перегукується з іменем даного var:

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


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

Лукас на 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 () на стероїдах, подібно до Крумо, але трохи ефективніше на об'єктах. Я хотів додати виявлення імені var і вийшов із цим, надихнувши публікацією Ніка Преста на цій сторінці. Він виявляє будь-який вираз, переданий як аргумент, не лише імена змінних.

Це лише функція обгортки, яка виявляє переданий вираз. Працює в більшості випадків. Він не буде працювати, якщо ви будете викликати функцію більше одного разу в одному рядку коду.

Це добре працює: померти ( перевірити ($ 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

Тексти перекладені на іспанській мові на цій сторінці, але код стислий і його легко зрозуміти.


1
Помилка, чи не це покладається на те, що ви встановили налагоджувач NuSphare?
Мауг каже, що повернемо Моніку

Я розмістив там спрощену версію цього коду. Також я змінив цю відповідь. Він повинен працювати зараз на кожній реалізації PHP5.
Себастьян Гріньолі

Настільки винахідливість, тому я посміхаюся кожного разу, коли бачу, що люди говорять "не можна зробити" або "неможливо", що включає в себе навіть самого Расмуса. Кудос Себастьяну та будь-кому іншому, хто, можливо, сприяв цій відповіді.
Сова

1
Дякую Ніч Сова, але я наполягаю на тому, що це не є куленепробивними (як йдеться у відповіді, воно не вдасться, якщо моя функція "перевірити ()" викликається більше одного разу в одному рядку!). Я б ніколи цього не використовував у виробництві. Це лише функція інспектора налагодження, яка ніколи не повинна дістатися до виробничого сервера.
Себастьян Гриньолі

7

З php.net

@ Александр - коротке рішення

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

)

1

Якщо змінна є взаємозамінною, ви повинні десь мати логіку, яка визначає, яка змінна використовується. Все, що вам потрібно зробити, - це ввести ім’я змінної у $variableцю логіку, а ви робите все інше.

Я думаю, що нам усім важко зрозуміти, для чого вам це потрібно. Зразок коду чи пояснення того, що ви насправді намагаєтесь зробити, можуть допомогти, але я підозрюю, що ви так, як подолати це.


1

Я фактично маю для цього дійсний випадок використання.

У мене є функція cacheVariable ($ var) (гаразд, у мене є кеш функцій ($ ключ, $ значення), але я хотів би мати функцію, як згадувалося).

Мета:

$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), але я лінивий, ви знаєте ...;)

Отже, я хочу - це функція, яка отримує ORIGINAL ім'я змінної, як вона була передана функції. Всередині функції немає можливості мені знати це, як здається. Передача get_defined_vars () за посиланням у другому прикладі вище допомогла мені (спасибі Жану-Жак Геган за цю ідею) дещо. Остання функція почала працювати, але вона все ще зберігала лише повернення локальної змінної ('змінної', а не 'кольорової').

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


1
Сама основна проблема полягає в тому, що ви передаєте значення у функції, а не в змінні . Змінні носять тимчасовий характер і мають особливий характер. Часто ім'я змінної може не бути ключем, під яким ви хочете кешувати значення, і часто ви відновите його до змінної, інакше названої так чи інакше (як у вашому прикладі). Якщо ви дійсно ліниві повторювати ім'я ключа, щоб запам'ятати змінну, використовуйте cacheVariable(compact('color')).
деге

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

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

Ви можете використовувати компакт (() для досягнення цього.

$FooBar = "a string";

$newArray = compact('FooBar');

Це створило б асоціативний масив із ім'ям змінної як ключовим. Потім ви можете провести цикл через масив, використовуючи ім'я ключа там, де вам це потрібно.

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

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 він порожній або null, він надрукує ім'я першого знайденого порожнього або null рядка.

Його можна використовувати як таке:

if (isset($FooBar) && !is_null($FooBar) && !empty($FooBar)) {
    $FooBar = "a string";
    $varname = trim(array_search($FooBar, $GLOBALS), " \t.");
}

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

@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]);
}

в основному він просто створює асоціативний масив, що містить один null / empty елемент, використовуючи в якості ключа змінну, для якої потрібно ім'я.

Потім ми отримуємо значення цього ключа за допомогою array_keys і повертаємо його.

Очевидно, що це стає безладним швидко і не хочеться в виробничих умовах, але це працює для проблеми, що подається.


1
Це значення змінної, а не ім'я змінної. Як зазначено в іншому місці, ім'я не переноситься через межі функцій.
Оуен Бересфорд,

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

-3

чому ми маємо використовувати глобалі, щоб отримати ім'я змінної ... ми можемо використовувати просто так, як нижче.

    $variableName = "ajaxmint";

    echo getVarName('$variableName');

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

6
Тому що ОП не знає назви змінної. Якби він це зробив, він би не потребував getVarName()функції. ;-)
FtDRbwLXw6

1
Це не повертає ім'я змінної як рядок, тому що '$variableName'це вже рядок, а не змінна. Якщо ви можете зробити цей трюк getVarName($variableName);, ви отримаєте підсумок :)
Daniel W.

-4

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

Тому що навіть якби ви використовували це у функції, ви отримаєте локальну назву змінної ...

У будь-якому випадку, ось посібник з роздумів на випадок, якщо там щось вам потрібно.


Друк ("foobar") не оброблятиме інші зміни.
Gary Willoughby

7
Використовуйте випадок: у вас є кілька пунктів налагодження в коді, що повертає демпінг того самого значення. Як ви знаєте, хто з них був страчений першим? Друк етикетки тоді дуже корисний.
приймає

Тоді ви не зробили достатньо програмування. Більшість мов, з якими я стикався, мають певний спосіб зробити це, як правило, просто.
b01

@ b01 Я багато зробив. Я прекрасно знаю, що існує багато мов, які це дозволяють, але це само по собі не означає багато. Багато мов пропонують певний спосіб зробити Goto легко, і це не означає, що ви повинні використовувати його, щоб не писати належного контролю потоку. На мій погляд, подібний випадок. Я не сумніваюся, що існують виправдані випадки, і саме тому мені було цікаво, чи правильно їх використовувати.
Вінко Врсалович
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.