Como obter um nome de variável como uma string no PHP?

201

Digamos que eu tenho esse código PHP:

$FooBar = "a string";

então eu preciso de uma função como esta:

print_var_name($FooBar);

que imprime:

FooBar

Alguma idéia de como conseguir isso? Isso é possível em PHP?

Gary Willoughby
fonte
9
Se você precisar disso para qualquer coisa além de depuração, estará fazendo algo gravemente errado. Qual é o seu caso de uso?
troelskn
10
Boa pergunta. Eu precisava do mesmo para depuração.
takeshin
17
+1 - Eu precisava disso para gerar automaticamente respostas XML ou JSON a partir de um objeto PHP modelo. Ter que quebrar o objeto dentro de outra rootName => modelObjectmatriz nomeada apenas adiciona profundidade desnecessária à resposta. Gostaria que isso fosse incorporado aos recursos de reflexão em tempo de execução da linguagem.
Anurag
4
Eu também precisava disso em uma função de log. Eu queria poder fazer o seguinte: log ($ didTheSystemBlowUp); Para aparecer no arquivo de log como: $ didTheSystemBlowUp = 'ainda não, mas muito em breve';
23412 SeanDowney
4
Além disso, isso pode ser útil ao chamar var_dump (); portanto, ao chamar várias variáveis ​​ao mesmo tempo, você não produz manualmente o nome var para distinguir entre as saídas de vardupms.
PHPst 3/12/12

Respostas:

37

Você pode usar get_defined_vars () para encontrar o nome de uma variável que tenha o mesmo valor daquele que você está tentando encontrar o nome. Obviamente, isso nem sempre funcionará, pois variáveis ​​diferentes geralmente têm os mesmos valores, mas é a única maneira em que posso pensar em fazer isso.

Edit: get_defined_vars () não parece estar funcionando corretamente, ele retorna 'var' porque $ var é usado na própria função. $ GLOBALS parece funcionar, então eu mudei para isso.

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

    return false;
}

Edit: para ficar claro, não há uma boa maneira de fazer isso no PHP, provavelmente porque você não deveria ter que fazer isso. Provavelmente, existem maneiras melhores de fazer o que você está tentando fazer.

Jeremy Ruten
fonte
2
Ahh Esteve devagar ;-) Pensei o mesmo, mas usando $ GLOBALS. Portanto, a comparação de identidade é verdadeira para valores escalares iguais ($ a = 'foo'; $ b = 'foo'; assert ($ a === $ b);)?
Argelbargel
Na verdade, agora que testei meu código, meu código sempre retornava 'var' porque está sendo usado na função. Quando eu uso $ GLOBALS, ele retorna o nome correto da variável por algum motivo. Então, alterarei o código acima para usar $ GLOBALS.
Jeremy Ruten 01/11/2008
Sim, eu percebi, mas get_defined_vars () foi suficiente ta.
Gary Willoughby
2
Existem muitos casos em que esse código não se comporta conforme o esperado.
troelskn
122
Este código está HORRÍVEL incorretamente. Verificar se a variável é igual à enviada por VALUE é uma ideia muito idiota. Miríades de variáveis ​​são NULL em qualquer ponto. Miríades estão definidas como 1. Isso é loucura.
Alex Weinstein
49

Também não consegui pensar em uma maneira de fazer isso de forma eficiente, mas vim com isso. Funciona para os usos limitados abaixo.

dar de ombros

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

Funciona com base na linha que chamou a função, onde encontra o argumento que você passou. Suponho que poderia ser expandido para trabalhar com vários argumentos, mas, como outros já disseram, se você pudesse explicar melhor a situação, outra solução provavelmente trabalhe melhor.

Nick Presta
fonte
2
Isso funciona, mas apenas se a função varName estiver definida no mesmo arquivo que a variável a ser encontrada.
rubo77
1
Aqui você encontrar uma melhor implementação que funciona ao longo de vários inclui: stackoverflow.com/a/19788805/1069083
rubo77
31

Você pode mudar sua abordagem e usar um nome de variável variável?

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

então você poderia apenas

print($var_name);

para obter

FooBar

Aqui está o link para o manual do PHP sobre Variáveis ​​variáveis


fonte
42
Eu trabalhei com um sistema que usava variáveis ​​variáveis ​​extensivamente. Deixe-me avisá-lo, fica muito fedido muito rápido!
Icode4food
3
Na maioria dos casos, o usuário deseja obter o nome e o valor de uma var. pense "function debugvar ($ varname)" e ele pretende chamá-lo "debugvar ('foo')" para que o debug mostre "foo = 123". com variável variável eles receberão 'foo' é indefinido.
gcb
basta olhar para o que você está realmente fazendo. Ali mesmo no seu exemplo, você realmente CRIA uma variável $FooBarcom o valor que a stringacabou de ler seu manual. Isso é horrível, imho. você nunca atribui $FooBarum valor à variável , mas está lá. OUCH
Toskan
20

Ninguém parece ter mencionado as razões fundamentais pelas quais isso é a) difícil eb) imprudente:

  • Uma "variável" é apenas um símbolo apontando para outra coisa. No PHP, ele aponta internamente para algo chamado "zval", que pode realmente ser usado para várias variáveis ​​simultaneamente, seja porque elas têm o mesmo valor (o PHP implementa algo chamado "copy-on-write" para que $foo = $barnão precise ser alocar memória extra imediatamente) ou porque foram atribuídos (ou passados ​​para uma função) por referência (por exemplo $foo =& $bar). Portanto, um zval não tem nome.
  • Quando você passa um parâmetro para uma função, está criando uma nova variável (mesmo que seja uma referência). Você poderia passar algo anônimo, "hello"mas, uma vez dentro da sua função, é qualquer variável que você nomear como. Isso é bastante fundamental para a separação de código: se uma função dependesse do que uma variável costumava ser chamada, seria mais como umgoto que uma função adequadamente separada.
  • Variáveis ​​globais são geralmente consideradas uma má ideia. Muitos exemplos aqui assumem que a variável que você deseja "refletir" pode ser encontrada em$GLOBALS , mas isso só será verdade se você estruturar mal o seu código e as variáveis ​​não tiverem escopo definido para alguma função ou objeto.
  • Os nomes de variáveis ​​existem para ajudar os programadores a ler seu código. Renomear variáveis ​​para melhor atender a sua finalidade é uma prática de refatoração muito comum, e o ponto principal é que isso não faz nenhuma diferença.

Agora, entendo o desejo disso para depuração (embora alguns dos usos propostos vão muito além disso), mas como uma solução generalizada não é tão útil quanto você imagina: se sua função de depuração diz que sua variável se chama "$ file ", ainda pode ser qualquer uma das dezenas de variáveis" $ file "no seu código ou uma variável que você chamou" $ filename ", mas que está passando para uma função cujo parâmetro é chamado" $ file ".

Uma informação muito mais útil é de onde no seu código a função de depuração foi chamada. Como você pode encontrar isso rapidamente no seu editor, pode ver qual variável estava produzindo para si mesmo e pode até passar expressões inteiras para ela de uma só vez (por exemplo debug('$foo + $bar = ' . ($foo + $bar))).

Para isso, você pode usar este snippet na parte superior da sua função de depuração:

$backtrace = debug_backtrace();
echo '# Debug function called from ' . $backtrace[0]['file'] . ' at line ' . $backtrace[0]['line'];
IMSoP
fonte
Já existem boas respostas. Então, isso é apenas ser pessimista, mesmo diante da realidade.
a20
@ a20 Todas as respostas têm fortes ressalvas sobre quando elas podem ser usadas e quando serão quebradas; nenhum é uma pesquisa simples de qualquer variável em seu nome, porque isso é de fato impossível. Alguns fazem muita reflexão descolada para fins de depuração, o que é bom; no entanto, minha opinião é de que é melhor você apenas exibir o número da linha e procurar a linha de origem - ou usar um depurador interativo como o XDebug.
IMSOP
14

É exatamente isso que você deseja - está pronta para usar a função "copiar e soltar" que ecoa o nome de uma determinada 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);
}

USO: print_var_name ($ FooBar)

PRINT: FooBar

DICA Agora você pode renomear a função e ela ainda funcionará e também poderá usá-la várias vezes em uma linha! Obrigado a @Cliffordlife

adilbo
fonte
3
Legal, obrigado por isso. Modifiquei ligeiramente a linha $ pat para $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';que não me importe como essa função de depuração é chamada, e recebo exatamente o que é passado para a função, por exemplo, $ hello, ou "hello" (larguei a correspondência $ da variável passada in, na mesma linha)
Cliffordlife
1
Código fantástico! Obrigado! No entanto, parece não funcionar em todas as instâncias. Resultado dos testes no meu ubuntu 18.04 com php 7.2.19: Não funciona quando usado várias vezes na mesma linha de código, independentemente de ser usado em uma ou em expressões separadas, pois retorna o nome da última variável do linha. Se for usado na mesma expressão, mas em linhas separadas, funciona. Utilizado em diferentes expressões em diferentes linhas, funciona.
Matty
1
também essa função deve estar em uma linha sem "var_dump" - com print_var_name, echo, var_dumpsaída de envio combinada$variable); echo ' '; var_dump($variable
BG Bruno
13

Lucas no PHP.net forneceu uma maneira confiável de verificar se existe uma variável. Em seu exemplo, ele itera através de uma cópia da matriz global variável (ou de uma matriz com escopo), altera o valor para um valor gerado aleatoriamente e verifica o valor gerado na matriz copiada.

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

Então tente:

$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

Não deixe de conferir o post dele no PHP.net: http://php.net/manual/en/language.variables.php

Trabalhador
fonte
Como você obtém o escopo atual em forma de matriz?
Sebastián Grignoli 27/10/10
Agradável! Para mim, apenas falta é break;quando encontrado igual no foreach + eu fiz a estrutura básica utilizável para obter automaticamente var_name também se definida dentro da função. Se você é muitas vezes Copie e Cole ou ter uma melhor idéia para melhorá-lo, usevariable_name( $variable, ( empty(__FUNCTION__) ? false : get_defined_vars() ) );
odie2
Esta é provavelmente a maneira mais rápida e limpa de fazer o trabalho, a depuração provavelmente inclui problemas de desempenho. A função deve retornar diretamente no loop foreach em vez de apenas atribuir sem interrupção. Dado que o GLOBALS pode ser grande, pode ser uma melhoria de desempenho.
John John
13

Eu criei uma função de inspeção por razões de depuração. É como print_r () em esteróides, muito parecido com o Krumo, mas um pouco mais eficaz em objetos. Eu queria adicionar a detecção de nome var e surgiu com isso, inspirado no post de Nick Presta nesta página. Ele detecta qualquer expressão passada como argumento, não apenas nomes de variáveis.

Essa é apenas a função do wrapper que detecta a expressão passada. Funciona na maioria dos casos. Não funcionará se você chamar a função mais de uma vez na mesma linha de código.

Isso funciona bem: die ( inspecione ($ this-> getUser () -> hasCredential ("excluir")) );

inspecionar () é a função que detectará a expressão passada.

Obtemos : $ 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);

}

Aqui está um exemplo da função do inspetor (e minha classe dInspect) em ação:

http://inspect.ip1.cc

Os textos estão em espanhol nessa página, mas o código é conciso e realmente fácil de entender.

Sebastián Grignoli
fonte
1
errrm, isso não depende de você ter o depurador NuSphare instalado?
Mawg diz que restabelece Monica
Publiquei uma versão simplificada desse código lá. Também modifiquei esta resposta. Ele deve ser executado em todas as implementações do PHP5 agora.
Sebastián Grignoli
Engenhosidade como essa é por que sorrio toda vez que vejo pessoas dizerem "não pode ser feito" ou "não é possível", o que inclui até o próprio Rasmus nesse caso. Parabéns a Sebastián e a qualquer pessoa que possa ter contribuído para esta resposta.
Night Owl
1
Obrigado Night Owl, mas insisto que isso não é à prova de balas (como a resposta indica, ela falhará se minha função "inspecionar ()" for chamada mais de uma vez em uma única linha!). Eu nunca usaria isso na produção. É apenas para uma função de inspetor de depuração que nunca deve chegar ao servidor de produção.
Sebastián Grignoli
7

Do php.net

@Alexandre - solução curta

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

@Lucas - use

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

fonte
4

Muitas respostas questionam a utilidade disso. No entanto, obter uma referência para uma variável pode ser muito útil. Especialmente em casos com objetos e $ this . Minha solução funciona com objetos e também como objetos definidos por propriedade:

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

Exemplo para o acima:

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
K. Brunner
fonte
2

Adaptado das respostas acima para muitas variáveis, com bom desempenho, apenas uma varredura do $ GLOBALS para muitas

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
fonte
1

Se a variável for intercambiável, você deverá ter lógica em algum lugar para determinar qual variável será usada. Tudo o que você precisa fazer é colocar o nome da variável em$variable nessa lógica enquanto faz todo o resto.

Acho que todos estamos tendo dificuldades para entender o que você precisa disso. Código de amostra ou uma explicação sobre o que você está realmente tentando fazer pode ajudar, mas eu suspeito que você é maneira, maneira cismar isso.

ceejayoz
fonte
1

Na verdade, tenho um caso de uso válido para isso.

Eu tenho uma função cacheVariable ($ var) (ok, eu tenho uma função de cache ($ key, $ value), mas eu gostaria de ter uma função conforme mencionado).

O objetivo é fazer:

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

...

// another session

...

$myColour = getCachedVariable('colour');

Eu tentei com

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
}

Eu também tentei com

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

Mas isso também falha ... :(

Claro, eu poderia continuar fazendo cache ('color', $ color), mas sou preguiçoso, você sabe ...;)

Então, o que eu quero é uma função que obtém o nome ORIGINAL de uma variável, pois foi passada para uma função. Dentro da função, não há como saber disso, ao que parece. Passar get_defined_vars () por referência no segundo exemplo acima me ajudou (obrigado a Jean-Jacques Guegan por essa ideia). A última função começou a funcionar, mas ainda continuava retornando a variável local ('variável', não 'cor').

Ainda não tentei usar get_func_args () e get_func_arg (), $ {} - constructos e key () combinados, mas presumo que ele também falhará.

Aron Cederholm
fonte
1
O problema muito básico é que você está passando valores para funções, não para variáveis . As variáveis ​​são temporárias e específicas ao seu escopo. Freqüentemente, o nome da variável pode não ser a chave na qual você deseja armazenar em cache o valor e, com frequência, você a restaurará para uma variável com nome diferente (como no exemplo). Se você estiver com preguiça de repetir o nome da chave para lembrar a variável, use cacheVariable(compact('color')).
deceze
1

Eu tenho isto:

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

Eu preferiria isso:

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

A função existente exibe uma caixa amarela com um contorno vermelho e mostra cada variável por nome e valor. A solução de matriz funciona, mas é um pouco complicada de digitar quando é necessária.

Esse é o meu caso de uso e, sim, tem a ver com a depuração. Eu concordo com aqueles que questionam seu uso de outra forma.

Will Fastie
fonte
1

Aqui está minha solução baseada em Jeremy Ruten

class DebugHelper {

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

usando isso

DebugHelper::printVarNames(
    $systemDefinedVars = get_defined_vars(),
    $varNames=array('yourVar00', 'yourVar01')
);
dakiquang
fonte
0

Por que você simplesmente não cria uma função simples e a diz?

/**
 * 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' );
Um homem velho
fonte
0

Eu estava procurando por isso, mas apenas decidi passar o nome, normalmente tenho o nome na área de transferência.

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

$fruit='apple';
VarTest($fruit,'fruit');
Kieron Axten
fonte
0

Você pode usar compact () para conseguir isso.

$FooBar = "a string";

$newArray = compact('FooBar');

Isso criaria uma matriz associativa com o nome da variável como chave. Em seguida, você pode percorrer a matriz usando o nome da chave onde for necessário.

foreach($newarray as $key => $value) {
    echo $key;
}
Budove
fonte
2
Legal, mas você precisa saber o nome da variável para usá-la. O OP está procurando determinar programaticamente o nome da variável.
codificador
0

Eu acho que você quer saber o nome da variável com o seu valor. Você pode usar uma matriz associativa para conseguir isso.

use nomes de variáveis ​​para chaves de matriz:

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

Quando você deseja obter nomes de variáveis, use array_keys($vars), ele retornará uma matriz desses nomes de variáveis ​​que foram usados ​​em sua $varsmatriz como chaves.

Janaka R Rajapaksha
fonte
Muito mais lento que os métodos mais comuns de declarar variáveis.
David Spector
0

Eu sei que isso é antigo e já respondeu, mas eu estava realmente procurando por isso. Estou postando esta resposta para economizar um pouco de tempo para as pessoas refinarem algumas das respostas.

Opção 1:

$data = array('$FooBar');  

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

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

Impressões:

FooBar

Por qualquer motivo que você se encontre em uma situação como essa, ele realmente funciona.

.
Opção 2:

$FooBar = "a string";  

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

Se $FooBarpossuir um valor único, ele imprimirá 'FooBar'. E se$FooBar estiver vazio ou nulo, imprimirá o nome da primeira cadeia vazia ou nula que encontrar.

Pode ser usado como tal:

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

Foi assim que eu fiz

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

Uso

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

Nota: alguns PHP 7 versões não funcionará corretamente devido a um bug no array_searchcom $GLOBALS, no entanto todas as outras versões funcionará.

Veja este https://3v4l.org/UMW7V

Chuva
fonte
-1

Use isso para desanexar variáveis ​​do usuário de global para verificar variáveis ​​no momento.

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
fonte
@IMSoP A julgar pelo resultado print implode( ' ', array_keys( $GLOBALS ));, parece uma suposição equivocada sobre o número de globais "padrão". No meu sistema, existem sete superglobais: $ _GET, $ _POST, $ _COOKIE, $ _FILES, $ _ENV, $ _REQUEST, $ _SERVER. E também há argv e argc. Portanto, o deslocamento deve ser 9. E não há sentido em especificar o terceiro parâmetro (comprimento), pois o padrão é apenas executar o final da matriz de qualquer maneira.
31418 Jeff
-2

Pode ser considerado rápido e sujo, mas minha preferência pessoal é usar uma função / método como este:

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

basicamente, apenas cria uma matriz associativa contendo um elemento nulo / vazio, usando como chave a variável para a qual você deseja o nome.

então obtemos o valor dessa chave usando array_keys e retornamos.

Obviamente, isso fica confuso rapidamente e não seria desejável em um ambiente de produção, mas funciona para o problema apresentado.

user3344253
fonte
1
Esse é o valor da variável, não o nome da variável. Como apontado em outro lugar, o nome não é portátil através dos limites das funções.
Owen Beresford
3
menos um porque essa função literalmente não faz nada além de retornar o trim ($ var);
Alexar
-3

por que temos que usar globais para obter o nome da variável ... podemos usar simplesmente como abaixo.

    $variableName = "ajaxmint";

    echo getVarName('$variableName');

    function getVarName($name) {
        return str_replace('$','',$name);
    }
Ajaxmint
fonte
6
Porque o OP não sabe o nome da variável. Se ele fizesse, ele não precisaria de uma getVarName()função. ;-)
FtDRbwLXw6
1
Isso não retorna o nome de uma variável como string, porque '$variableName'já é uma string, não uma variável. Se você pode fazer este truque com getVarName($variableName);, você recebe um upvote :)
Daniel W.
-4

Eu realmente não consigo ver o caso de uso ... Se você digitar print_var_name ($ foobar), o que há de tão difícil (e diferente) em digitar print ("foobar")?

Porque, mesmo que você usasse isso em uma função, obteria o nome local da variável ...

De qualquer forma, aqui está o manual de reflexão , caso haja algo que você precisa.

Vinko Vrsalovic
fonte
A impressão ("foobar") não manipula outros vars.
Gary Willoughby
7
Caso de uso: você tem alguns pontos de depuração no código retornando o dumping do mesmo valor. Como você sabe qual foi executado primeiro? Imprimir uma etiqueta é muito útil então.
takeshin
Então você não fez programação suficiente. A maioria dos idiomas que conheci tem alguma maneira de fazer isso, geralmente simples.
b01 30/08/12
@ b01 Eu já fiz bastante. Estou perfeitamente ciente de que existem muitos idiomas que permitem isso, mas isso por si só não significa muito. Muitos idiomas oferecem alguma maneira de fazer goto facilmente e isso não significa que você deve usá-lo para evitar o controle adequado do fluxo. Este é um caso semelhante na minha opinião. Não duvido que haja casos justificáveis, e é por isso que estava pensando em casos de uso adequados para isso.
Vinko Vrsalovic 31/08/2012