假设我有这样的PHP代码:

$FooBar = "a string";

然后我需要一个这样的函数:

print_var_name($FooBar);

打印:

FooBar

有什么想法如何实现这一点?这在PHP中可能吗?


当前回答

我也想不出有效的方法但我想到了这个。对于下面的有限用途,它是有效的。

耸耸肩

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

它基于调用函数的行来工作,在那里它可以找到传入的参数。我认为它可以扩展到多个参数,但是,就像其他人说的,如果你能更好地解释情况,另一个解决方案可能会更好。

其他回答

我知道这个问题很老了,而且已经有人回答了,但我其实是在找这个。我把这个答案贴出来是为了给大家节省一点时间来完善一些答案。

选项1:

$data = array('$FooBar');  

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

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

打印:

FooBar

不管出于什么原因,你会发现自己处于这样的情况下,它确实有效。

. 选项2:

$FooBar = "a string";  

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

如果$FooBar拥有一个唯一的值,它将打印'FooBar'。如果$FooBar为空或空,它将打印找到的第一个空字符串或空字符串的名称。

它可以这样使用:

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

我认为你想知道变量名和它的值。您可以使用关联数组来实现这一点。

为数组键使用变量名:

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

当你想获取变量名时,使用array_keys($vars),它将返回一个数组,这些变量名是你的$vars数组中使用的键。

似乎没有人提到这是a)困难和b)不明智的根本原因:

A "variable" is just a symbol pointing at something else. In PHP, it internally points to something called a "zval", which can actually be used for multiple variables simultaneously, either because they have the same value (PHP implements something called "copy-on-write" so that $foo = $bar doesn't need to allocate extra memory straight away) or because they have been assigned (or passed to a function) by reference (e.g. $foo =& $bar). So a zval has no name. When you pass a parameter to a function you are creating a new variable (even if it's a reference). You could pass something anonymous, like "hello", but once inside your function, it's whatever variable you name it as. This is fairly fundamental to code separation: if a function relied on what a variable used to be called, it would be more like a goto than a properly separate function. Global variables are generally considered a bad idea. A lot of the examples here assume that the variable you want to "reflect" can be found in $GLOBALS, but this will only be true if you've structured your code badly and variables aren't scoped to some function or object. Variable names are there to help programmers read their code. Renaming variables to better suit their purpose is a very common refactoring practice, and the whole point is that it doesn't make any difference.

现在,我理解这种调试的愿望(尽管一些建议的用法远远超出了这一点),但作为一种通用的解决方案,它实际上并没有你想象的那么有用:如果你的调试函数说你的变量是“$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'];

这正是你想要的-这是一个随时可以使用的“复制并导入”函数,它会回显给定变量的名称:

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 '<pre>' . trim($var) . ' = ' . print_r(current(func_get_args()), true) . '</pre>';
}

用法:print_var_name ($ FooBar)

打印:FooBar

提示 现在你可以重命名函数,它仍然可以工作,也可以在一行中多次使用该函数!感谢@Cliffordlife 我添加了一个更好的输出!多亏了@Blue-Water

其他用途:

耸耸肩

function varsToArrayAssoc(...$arguments){
  
    $bt   = debug_backtrace();
    $file = file($bt[0]['file']);
    $src  = $file[$bt[0]['line']-1];
    $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';
    $vars  =explode(',',substr_replace(trim(preg_replace($pat, '$2', $src)) ,"", -1));
    $result=[];
    foreach(func_get_args() as $key=>$v){
        $index=trim(explode('$',$vars[$key])[1]);
        $result[$index]=$v;
    }
    return $result;
}

$a=12;
$b=13;
$c=123;
$d='aa';

var_dump(varsToArrayAssoc($a,$b,$c,$d));