假设我有这样的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
)

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

其他回答

我有这个:

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

我更喜欢这样:

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

现有函数显示一个带有红色轮廓的黄色框,并按名称和值显示每个变量。数组解决方案是可行的,但在需要时输入有点复杂。

这就是我的用例,是的,它确实与调试有关。我同意那些质疑其其他用途的人。

net上的Lucas提供了一种可靠的方法来检查变量是否存在。在他的示例中,他遍历变量的全局变量数组(或作用域数组)的副本,将值更改为随机生成的值,并在复制的数组中检查生成的值。

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

为什么我们必须使用全局变量来获取变量名…我们可以像下面这样简单地使用。

    $variableName = "ajaxmint";

    echo getVarName('$variableName');

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

许多回复质疑这样做的用处。然而,获取变量的引用是非常有用的。特别是在有对象和$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

这是我基于杰里米·鲁滕的解决方案

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