假设我有这样的PHP代码:

$FooBar = "a string";

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

print_var_name($FooBar);

打印:

FooBar

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


当前回答

从上面的答案改编为许多变量,具有良好的性能,只需一个$GLOBALS扫描许多

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
        )

)

其他回答

我实际上有一个有效的用例。

我有一个函数cacheVariable($var)(好吧,我有一个函数缓存($key, $value),但我想有一个函数如上所述)。

目的是:

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

...

// another session

...

$myColour = getCachedVariable('colour');

我试过了

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
}

我也试过

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

但这也失败了……:(

当然,我可以继续做缓存(' color ', $ color),但我很懒,你知道…;)

所以,我想要的是一个函数,它得到一个变量的原始名称,因为它被传递给一个函数。在函数内部,我不可能知道这一点。在上面的第二个例子中,通过引用传递get_defined_vars()在一定程度上帮助了我(感谢Jean-Jacques Guegan的这个想法)。后一个函数开始工作,但它仍然只返回局部变量('variable',而不是' color ')。

我还没有尝试使用get_func_args()和get_func_arg(), ${}-构造和key()组合,但我认为它也会失败。

如果变量是可交换的,那么必须在某个地方有逻辑来决定使用哪个变量。你所需要做的就是在你做其他事情的时候,把变量名放在这个逻辑中的$variable中。

我想我们都很难理解你需要这个做什么。示例代码或对实际要做的事情的解释可能会有所帮助,但我怀疑您想得太多了。

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

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

为数组键使用变量名:

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

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

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

耸耸肩

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

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