¿Cómo obtener un nombre de variable como una cadena en PHP?
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?
Tampoco se me ocurrió una manera de hacer esto de manera eficiente, pero se me ocurrió esto. Funciona para los usos limitados que se indican 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 usted pasó. Supongo que podría expandirse para que funcione con múltiples argumentos pero, como han dicho otros, si pudiera explicar mejor la situación, probablemente otra solución sería trabaja mejor.
Podrías usar get_defined_vars() para encontrar el nombre de una variable que tenga el mismo valor que aquella cuyo nombre estás tratando de encontrar. Obviamente, esto no siempre funcionará, ya que diferentes variables suelen tener los mismos valores, pero es la única forma que se me ocurre para hacerlo.
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 cambié 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 existe una buena manera de hacer esto en PHP, probablemente porque no deberías tener que hacerlo. Probablemente haya mejores formas de hacer lo que estás intentando hacer.
¿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
Nadie parece haber mencionado las razones fundamentales por las que esto es a) difícil yb) imprudente:
- Una "variable" es sólo un símbolo que apunta a otra cosa. En PHP, apunta internamente 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 no es
$foo = $bar
necesario asignar memoria adicional de inmediato) o porque han sido asignados (o pasados a una función) por referencia (por ejemplo$foo =& $bar
). Entonces un zval no tiene nombre. - Cuando pasas un parámetro a una función estás creando una nueva variable (incluso si es una referencia). Podrías pasar algo anónimo, como
"hello"
, pero una vez dentro de tu función, es cualquier variable que le pongas el nombre. Esto es bastante fundamental para la separación de códigos: si una función dependiera de cómo solía llamarse una variable, sería más una funcióngoto
que una función propiamente separada. - Las variables globales generalmente se consideran una mala idea. Muchos de los ejemplos aquí asumen que la variable que desea "reflejar" se puede encontrar en
$GLOBALS
, pero esto solo será cierto si ha estructurado mal su código y las variables no están limitadas a alguna función u objeto. - Los nombres de las variables están ahí para ayudar a los programadores a leer su código. Cambiar el nombre de las variables para que se adapten 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á), 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 ", aún podría ser cualquiera 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 llame "$file".
Una información mucho más útil es desde qué parte de su código se llamó a la función de depuración. Dado que puede encontrar esto rápidamente en su editor, puede ver qué variable estaba generando usted mismo e incluso puede pasarle expresiones completas de una sola vez (por ejemplo, debug('$foo + $bar = ' . ($foo + $bar))
).
Para eso, puedes usar este fragmento en la parte superior de tu función de depuración:
$backtrace = debug_backtrace();
echo '# Debug function called from ' . $backtrace[0]['file'] . ' at line ' . $backtrace[0]['line'];