¿Cómo obtener un nombre de variable como una cadena en PHP?

201

Digamos que tengo este código PHP:

$FooBar = "a string";

Entonces necesito una función como esta:

print_var_name($FooBar);

que imprime:

FooBar

¿Alguna idea de cómo lograr esto? ¿Es esto posible en PHP?

Gary Willoughby
fuente
9
Si necesita esto para otra cosa que no sea la depuración, está haciendo algo gravemente incorrecto. ¿Cuál es su caso de uso?
troelskn 01 de
10
Buena pregunta. Necesitaba lo mismo para la depuración.
takeshin
17
+1: necesitaba esto para generar automáticamente respuestas XML o JSON de un modelo de objeto PHP. Tener que envolver el objeto dentro de otra rootName => modelObjectmatriz con nombre solo agrega profundidad innecesaria a la respuesta. Ojalá esto estuviera integrado en las capacidades de reflexión del tiempo de ejecución del lenguaje.
Anurag
44
También tuve una necesidad de esto en una función de registro. Quería poder hacer lo siguiente: log ($ didTheSystemBlowUp); Para aparecer en el archivo de registro como: $ didTheSystemBlowUp = 'todavía no, pero muy pronto';
SeanDowney
44
Además, esto puede ser útil al llamar a var_dump (), de modo que cuando llama al mismo tiempo a varias variables, no ha generado manualmente el nombre de var para distinguir entre las salidas de vardupms.
PHPst

Respuestas:

37

Puede usar get_defined_vars () para encontrar el nombre de una variable que tiene el mismo valor que el que está tratando de encontrar el nombre. Obviamente, esto no siempre funcionará, ya que las diferentes variables a menudo tienen los mismos valores, pero es la única forma en que puedo pensar en hacer esto.

Editar: get_defined_vars () no parece funcionar correctamente, devuelve 'var' porque $ var se usa en la función misma. $ GLOBALS parece funcionar, así que lo he cambiado a eso.

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

    return false;
}

Editar: para ser claros, no hay una buena manera de hacer esto en PHP, probablemente porque no debería tener que hacerlo. Probablemente hay mejores formas de hacer lo que intentas hacer.

Jeremy Ruten
fuente
2
Ahh Ha sido lento ;-) Pensé lo mismo, pero usé $ GLOBALS en su lugar. Entonces, la comparación de identidad produce verdadero para valores escalares iguales ($ a = 'foo'; $ b = 'foo'; afirmar ($ a === $ b);)?
Argelbargel
En realidad, ahora que he probado mi código, mi código siempre devolvió 'var' porque se está utilizando en la función. Cuando uso $ GLOBALS en su lugar, devuelve el nombre de variable correcto por alguna razón. Así que cambiaré el código anterior para usar $ GLOBALS.
Jeremy Ruten el
Sí, me di cuenta, pero get_defined_vars () fue suficiente para ta.
Gary Willoughby el
2
Hay muchos casos en los que este código no se comportará como se esperaba.
troelskn 01 de
122
Este código es HORRIBLEMENTE incorrecto. Verificar si la variable f es la misma que la que envía VALUE es una idea muy tonta. Miles de variables son NULL en cualquier punto dado. Las miríadas se establecen en 1. Esto es una locura.
Alex Weinstein
49

Tampoco se me ocurrió una manera de hacer esto de manera eficiente, pero se me ocurrió esto. Funciona, para los usos limitados a continuación.

encogimiento de hombros

<?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 en función de la línea que llamó a la función, donde encuentra el argumento que ingresó. Supongo que podría expandirse para trabajar con múltiples argumentos, pero, como han dicho otros, si pudiera explicar mejor la situación, probablemente otra solución trabaja mejor.

Nick Presta
fuente
2
Esto funciona, pero solo si la función varName está definida en el mismo archivo que la variable que se encuentra.
rubo77
1
Aquí encontrará una mejor implementación que funciona en varios
casos
31

¿Podría considerar cambiar su enfoque y usar un nombre de variable variable?

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

entonces podrías simplemente

print($var_name);

Llegar

FooBar

Aquí está el enlace al manual de PHP sobre variables variables


fuente
42
He trabajado con un sistema que usaba variables variables ampliamente. Déjame advertirte, ¡se vuelve realmente maloliente muy rápido!
Icode4food
3
En la mayoría de los casos, el usuario desea obtener el nombre y el valor de una var. piense "function debugvar ($ varname)" y tiene la intención de llamarlo "debugvar ('foo')" para que la depuración muestre "foo = 123". con variable variable obtendrán 'foo' no está definido.
gcb
solo mira lo que realmente estás haciendo. Justo allí, en su ejemplo, usted CREA una variable $FooBarcon el valor que a stringacaba de leer su manual. Esto es horrible en mi humilde opinión. nunca asigna $FooBarun valor a la variable , pero está ahí. OUCH
Toskan
20

Nadie parece haber mencionado las razones fundamentales por las cuales esto es a) difícil yb) imprudente:

  • Una "variable" es solo un símbolo que apunta a otra cosa. En PHP, internamente apunta a algo llamado "zval", que en realidad puede usarse para múltiples variables simultáneamente, ya sea porque tienen el mismo valor (PHP implementa algo llamado "copiar en escritura", por lo que $foo = $barno necesita asignar memoria adicional de inmediato) o porque se les ha asignado (o pasado a una función) por referencia (por ejemplo $foo =& $bar) Entonces un zval no tiene nombre.
  • Cuando pasa un parámetro a una función, está creando una nueva variable (incluso si es una referencia). Podría pasar algo anónimo, como "hello", pero una vez dentro de su función, es la variable que le asigne. Esto es bastante fundamental para la separación de código: si una función dependía de lo que solía llamarse una variable , sería más una función gotoque una función propiamente separada.
  • Las variables globales generalmente se consideran una mala idea. Muchos de los ejemplos aquí suponen que se puede encontrar la variable que desea "reflejar" $GLOBALS, pero esto solo será cierto si ha estructurado mal su código y las variables no tienen ámbito para alguna función u objeto.
  • Los nombres de variables están ahí para ayudar a los programadores a leer su código. Cambiar el nombre de las variables para que se adapte mejor a su propósito es una práctica de refactorización muy común, y el punto es que no hace ninguna diferencia.

Ahora, entiendo el deseo de esto para la depuración (aunque algunos de los usos propuestos van mucho más allá de eso), pero como solución generalizada, en realidad no es tan útil como podría pensar: si su función de depuración dice que su variable se llama "$ file ", podría seguir siendo una de las docenas de variables" $ file "en su código, o una variable que haya llamado" $ filename "pero que esté pasando a una función cuyo parámetro se llama" $ file ".

Una información mucho más útil es desde dónde se llamó a la función de depuración en su código. Como puede encontrar esto rápidamente en su editor, puede ver qué variable estaba generando por sí mismo, e incluso puede pasar expresiones completas a la vez (por ejemplo debug('$foo + $bar = ' . ($foo + $bar))).

Para eso, puede usar este fragmento en la parte superior de su función de depuración:

$backtrace = debug_backtrace();
echo '# Debug function called from ' . $backtrace[0]['file'] . ' at line ' . $backtrace[0]['line'];
IMSoP
fuente
Ya hay algunas buenas respuestas. Entonces, esto es ser pesimista incluso frente a la realidad.
a20
@ a20 Todas las respuestas tienen fuertes advertencias sobre cuándo se pueden usar y cuándo se romperán; none es una búsqueda simple de cualquier variable a su nombre, porque de hecho es imposible. Algunos hacen mucha reflexión funky para propósitos de depuración, lo cual está bien; Sin embargo, mi opinión es que es mejor que solo envíe el número de línea y busque la línea de origen usted mismo, o que use un depurador interactivo como XDebug.
IMSoP
14

Esto es exactamente lo que desea: es una función "copiar y soltar" lista para usar que hace eco del nombre de una variable dada:

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)

IMPRESIÓN: FooBar

SUGERENCIA ¡ Ahora puede cambiar el nombre de la función y seguirá funcionando y también usar la función varias veces en una línea! Gracias a @Cliffordlife

adilbo
fuente
3
Genial, gracias por esto. Modifiqué la línea $ pat de $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';esta manera, no me importa cómo se llama esta función de depuración, y obtengo exactamente lo que se pasa a la función, es decir, $ hello o "hello" (eliminé la coincidencia de $ para la variable pasada en, en la misma línea)
Cliffordlife
1
Fantástico pedazo de código! ¡Gracias! Sin embargo, no parece funcionar en todos los casos. Resultado de la prueba en mi ubuntu 18.04 con php 7.2.19: no funciona cuando se usa varias veces en la misma línea de código, independientemente de si se usa en una o en expresiones separadas, porque luego devuelve el nombre de la última variable de la línea. Si se usa en la misma expresión pero en líneas separadas, funciona. Utilizado en diferentes expresiones en diferentes líneas funciona.
Matty
1
también esa función debe estar en una línea sin "var_dump" - con print_var_name, echo, var_dumpsalida de envío combinada$variable); echo ' '; var_dump($variable
BG Bruno
13

Lucas en PHP.net proporcionó una forma confiable de verificar si existe una variable. En su ejemplo, itera a través de una copia de la matriz de variables globales (o una matriz de ámbito) de variables, cambia el valor a un valor generado aleatoriamente y comprueba el valor generado en la 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;
}

Entonces intenta:

$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

Asegúrese de revisar su publicación en PHP.net: http://php.net/manual/en/language.variables.php

Obrero
fuente
¿Cómo se obtiene el alcance actual en forma de matriz?
Sebastián Grignoli
¡Agradable! Para mí, solo falta break;cuando se encuentra igual en foreach + Hice una estructura básica utilizable para obtener automáticamente var_name también si se define dentro de la función. Si a menudo copia y pega o tiene una mejor idea para mejorarlo, usevariable_name( $variable, ( empty(__FUNCTION__) ? false : get_defined_vars() ) );
odie2
Esta es probablemente la forma más rápida y limpia de hacer el trabajo, la depuración probablemente incluye problemas de rendimiento. La función debe regresar directamente en el bucle foreach en lugar de simplemente asignar sin interrupción. Dado que GLOBALS puede ser grande, puede ser una mejora en el rendimiento.
John
13

Hice una función de inspección por razones de depuración. Es como print_r () en esteroides, muy parecido a Krumo pero un poco más efectivo en objetos. Quería agregar la detección de nombre var y salí con esto, inspirado en la publicación de Nick Presta en esta página. Detecta cualquier expresión pasada como argumento, no solo nombres de variables.

Esta es solo la función de contenedor que detecta la expresión pasada. Funciona en la mayoría de los casos. No funcionará si llama a la función más de una vez en la misma línea de código.

Esto funciona bien: morir ( inspeccionar ($ this-> getUser () -> hasCredential ("eliminar")) );

inspeccionar () es la función que detectará la expresión pasada.

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

}

Aquí hay un ejemplo de la función de inspector (y mi clase dInspect) en acción:

http://inspect.ip1.cc

Los textos están en español en esa página, pero el código es conciso y realmente fácil de entender.

Sebastián Grignoli
fuente
1
errrm, ¿eso no depende de que tengas instalado el depurador NuSphare?
Mawg dice que reinstalar a Monica el
Publiqué una versión simplificada de este código allí. También modifiqué esta respuesta. Debería ejecutarse en todas las implementaciones de PHP5 ahora.
Sebastián Grignoli
Ingenio como este es la razón por la que sonrío cada vez que veo que la gente dice "no se puede hacer" o "no es posible", lo que incluye incluso al propio Rasmus en este caso. Felicitaciones a Sebastián y a cualquier otra persona que haya contribuido a esta respuesta.
Night Owl
1
Gracias Night Owl, pero insisto en que esto no es a prueba de balas (como dice la respuesta, fallará si mi función "inspeccionar ()" se llama más de una vez en una sola línea). Nunca usaría esto en producción. Es solo para una función de inspector de depuración que nunca debería llegar al servidor de producción.
Sebastián Grignoli
7

De php.net

@Alexandre - solución corta

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

@Lucas - uso

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

fuente
4

Muchas respuestas cuestionan la utilidad de esto. Sin embargo, obtener una referencia para una variable puede ser muy útil. Especialmente en casos con objetos y $ this . Mi solución funciona con objetos y también como objetos definidos de propiedad:

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

Ejemplo de lo anterior:

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
fuente
2

Adaptado de las respuestas anteriores para muchas variables, con buen rendimiento, solo un escaneo de $ GLOBALS para muchos

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
        )

)
usuario1933288
fuente
1

Si la variable es intercambiable, debe tener lógica en algún lugar que determine qué variable se usa. Todo lo que necesitas hacer es poner el nombre de la variable $variabledentro de esa lógica mientras haces todo lo demás.

Creo que a todos nos cuesta entender para qué lo necesitas. Código de ejemplo o una explicación de lo que en realidad estás tratando de hacer ayuda fuerza, pero sospecho que es manera, forma overthinking esto.

ceejayoz
fuente
1

De hecho, tengo un caso de uso válido para esto.

Tengo una función cacheVariable ($ var) (ok, tengo una función cache ($ key, $ value), pero me gustaría tener una función como se mencionó).

El propósito es hacer:

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

...

// another session

...

$myColour = getCachedVariable('colour');

He intentado con

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
}

También he intentado con

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

Pero esto también falla ... :(

Claro, podría seguir haciendo caché ('color', $ color), pero soy vago, ya sabes ...;)

Entonces, lo que quiero es una función que obtenga el nombre ORIGINAL de una variable, ya que se pasó a una función. Dentro de la función no hay forma de que pueda saber eso, como parece. Pasar get_defined_vars () por referencia en el segundo ejemplo anterior me ayudó (Gracias a Jean-Jacques Guegan por esa idea) de alguna manera. La última función comenzó a funcionar, pero solo seguía devolviendo la variable local ('variable', no 'color').

Todavía no he intentado usar get_func_args () y get_func_arg (), $ {} - constructos y key () combinados, pero supongo que también fallará.

Aron Cederholm
fuente
1
El problema muy básico es que estás pasando valores a funciones, no a variables . Las variables son temporales y particulares a su alcance. A menudo, el nombre de la variable puede no ser la clave con la que desea almacenar el valor en caché y, a menudo, lo restaurará a una variable con un nombre diferente (como lo hace en su ejemplo). Si realmente eres demasiado vago para repetir el nombre de la clave para recordar la variable, usa cacheVariable(compact('color')).
deceze
1

Tengo esto:

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

Prefiero esto:

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

La función existente muestra un cuadro amarillo con un contorno rojo y muestra cada variable por nombre y valor. La solución de matriz funciona, pero es un poco complicado para escribir cuando es necesario.

Ese es mi caso de uso y sí, tiene que ver con la depuración. Estoy de acuerdo con aquellos que cuestionan su uso de otra manera.

Will Fastie
fuente
1

Aquí está mi solución basada en Jeremy Ruten

class DebugHelper {

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

usándolo

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

¿Por qué no construyes una función simple y la dices?

/**
 * 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' );
Un hombre viejo
fuente
0

Estaba buscando esto, pero decidí pasar el nombre, generalmente tengo el nombre en el portapapeles de todos modos.

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

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

Puede usar compact () para lograr esto.

$FooBar = "a string";

$newArray = compact('FooBar');

Esto crearía una matriz asociativa con el nombre de la variable como clave. A continuación, puede recorrer la matriz utilizando el nombre de la clave donde la necesita.

foreach($newarray as $key => $value) {
    echo $key;
}
Budove
fuente
2
Genial, pero tienes que saber el nombre de la variable para usarlo. OP está buscando determinar mediante programación el nombre de la variable.
un codificador
0

Creo que quieres saber el nombre de la variable con su valor. Puede usar una matriz asociativa para lograr esto.

use nombres de variables para claves de matriz:

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

Cuando desee obtener nombres de variables, use array_keys($vars), devolverá una matriz de esos nombres de variables que se usaron en su $varsmatriz como claves.

Janaka R Rajapaksha
fuente
Mucho más lento que los métodos más habituales para declarar variables.
David Spector
0

Sé que esto es viejo y ya respondió, pero en realidad estaba buscando esto. Estoy publicando esta respuesta para ahorrarle a la gente un poco de tiempo refinando algunas de las respuestas.

Opción 1:

$data = array('$FooBar');  

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

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

Huellas dactilares:

FooBar

Por cualquier razón que te encuentres en una situación como esta, realmente funciona.

.
Opcion 2:

$FooBar = "a string";  

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

Si $FooBartiene un valor único, imprimirá 'FooBar'. Si $FooBarestá vacío o nulo, imprimirá el nombre de la primera cadena vacía o nula que encuentre.

Se podría usar como tal:

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

Así lo hice yo

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: algunas versiones de PHP 7 no funcionarán correctamente debido a un error en array_searchla $GLOBALS, sin embargo todas las otras versiones funcionarán.

Ver esto https://3v4l.org/UMW7V

Lluvia
fuente
-1

Use esto para separar las variables de usuario de global para verificar la variable en este 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 ; 
    }
}
usuario1446000
fuente
@IMSoP A juzgar por el resultado print implode( ' ', array_keys( $GLOBALS ));, parece una suposición errónea sobre el número de globales "por defecto". En mi sistema hay siete superglobales: $ _GET, $ _POST, $ _COOKIE, $ _FILES, $ _ENV, $ _REQUEST, $ _SERVER. Y también hay argv y argc. Por lo tanto, el desplazamiento debe ser 9. Y no tiene sentido especificar el tercer parámetro (longitud) ya que el valor predeterminado es simplemente ejecutar hasta el final de la matriz de todos modos.
Jeff
-2

Puede considerarse rápido y sucio, pero mi preferencia personal es usar una función / método como este:

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

básicamente solo crea una matriz asociativa que contiene un elemento nulo / vacío, utilizando como clave la variable para la que desea el nombre.

luego obtenemos el valor de esa clave usando array_keys y la devolvemos.

obviamente, esto se vuelve desordenado rápido y no sería deseable en un entorno de producción, pero funciona para el problema presentado.

user3344253
fuente
1
Ese es el valor de la variable, no el nombre de la variable. Como se señaló en otra parte, el nombre no es portátil a través de los límites de la función.
Owen Beresford
3
menos uno porque esta función no hace más que devolver el recorte ($ var);
Alexar
-3

por qué tenemos que usar globales para obtener el nombre de la variable ... podemos usar simplemente como a continuación.

    $variableName = "ajaxmint";

    echo getVarName('$variableName');

    function getVarName($name) {
        return str_replace('$','',$name);
    }
Ajaxmint
fuente
66
Porque el OP no conoce el nombre de la variable. Si lo hiciera, no necesitaría una getVarName()función. ;-)
FtDRbwLXw6
1
Esto no devuelve el nombre de una variable como cadena, porque '$variableName'ya es una cadena, no una variable. Si puedes hacer este truco getVarName($variableName);, obtienes un voto a favor :)
Daniel W.
-4

Realmente no veo el caso de uso ... Si va a escribir print_var_name ($ foobar), ¿qué es tan difícil (y diferente) de escribir print ("foobar") en su lugar?

Porque incluso si usaras esto en una función, obtendrías el nombre local de la variable ...

En cualquier caso, aquí está el manual de reflexión en caso de que haya algo que necesite allí.

Vinko Vrsalovic
fuente
Print ("foobar") no manejará otros vars.
Gary Willoughby el
77
Caso de uso: tiene pocos puntos de depuración en el código que devuelve volcar el mismo valor. ¿Cómo sabes cuál fue ejecutado primero? Imprimir una etiqueta es muy útil entonces.
takeshin
Entonces no has hecho suficiente programación. La mayoría de los idiomas que he encontrado tienen alguna forma de hacerlo, generalmente simple.
b01
@ b01 He hecho mucho. Soy perfectamente consciente de que hay muchos idiomas que permiten esto, pero eso por sí solo no significa mucho. Muchos idiomas ofrecen alguna manera de hacer goto fácilmente y eso no significa que deba usarlo para evitar escribir el control de flujo adecuado. Este es un caso similar en mi opinión. No dudo que haya casos justificables, y es por eso que me preguntaba sobre los casos de uso adecuados para ello.
Vinko Vrsalovic