假设我有这样的PHP代码:

$FooBar = "a string";

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

print_var_name($FooBar);

打印:

FooBar

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


当前回答

我就是这么做的

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

使用

$city  = "San Francisco";
echo getVar($city); // city

注意:一些PHP 7版本将不能正常工作,因为array_search与$GLOBALS的错误,但所有其他版本都可以正常工作。

请看这个https://3v4l.org/UMW7V

其他回答

其他用途:

耸耸肩

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

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

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

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

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

从php.net

@Alexandre -简短的解决方案

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

@Lucas - usage

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