假设我有这样的PHP代码:

$FooBar = "a string";

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

print_var_name($FooBar);

打印:

FooBar

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


当前回答

它可能被认为是快速和肮脏的,但我个人倾向于使用这样的函数/方法:

public function getVarName($var) {      
  $tmp = array($var => '');
  $keys = array_keys($tmp);
  return trim($keys[0]);
}

基本上,它只是创建一个包含一个空/空元素的关联数组,使用需要名称的变量作为键。

然后使用array_keys获取该键的值并返回。

显然,这很快就会变得混乱,在生产环境中不可取,但它可以解决所提出的问题。

其他回答

出于调试的原因,我做了一个检查函数。它就像print_r()的类固醇,很像Krumo,但对对象更有效一点。我想添加var名称检测,灵感来自于Nick Presta的帖子。它检测作为参数传递的任何表达式,而不仅仅是变量名。

这只是检测传递表达式的包装器函数。 大多数案子都没问题。 如果在同一行代码中多次调用该函数,则它将不起作用。

这很好: 死(检查($ this - > getUser()——> hasCredential(“删除”)));

Inspect()是检测传递表达式的函数。

我们得到:$this->getUser()->hasCredential("delete")

function inspect($label, $value = "__undefin_e_d__")
{
    if($value == "__undefin_e_d__") {

        /* The first argument is not the label but the 
           variable to inspect itself, so we need a label.
           Let's try to find out it's name by peeking at 
           the source code. 
        */

        /* The reason for using an exotic string like 
           "__undefin_e_d__" instead of NULL here is that 
           inspected variables can also be NULL and I want 
           to inspect them anyway.
        */

        $value = $label;

        $bt = debug_backtrace();
        $src = file($bt[0]["file"]);
        $line = $src[ $bt[0]['line'] - 1 ];

        // let's match the function call and the last closing bracket
        preg_match( "#inspect\((.+)\)#", $line, $match );

        /* let's count brackets to see how many of them actually belongs 
           to the var name
           Eg:   die(inspect($this->getUser()->hasCredential("delete")));
                  We want:   $this->getUser()->hasCredential("delete")
        */
        $max = strlen($match[1]);
        $varname = "";
        $c = 0;
        for($i = 0; $i < $max; $i++){
            if(     $match[1]{$i} == "(" ) $c++;
            elseif( $match[1]{$i} == ")" ) $c--;
            if($c < 0) break;
            $varname .=  $match[1]{$i};
        }
        $label = $varname;
    }

    // $label now holds the name of the passed variable ($ included)
    // Eg:   inspect($hello) 
    //             => $label = "$hello"
    // or the whole expression evaluated
    // Eg:   inspect($this->getUser()->hasCredential("delete"))
    //             => $label = "$this->getUser()->hasCredential(\"delete\")"

    // now the actual function call to the inspector method, 
    // passing the var name as the label:

      // return dInspect::dump($label, $val);
         // UPDATE: I commented this line because people got confused about 
         // the dInspect class, wich has nothing to do with the issue here.

    echo("The label is: ".$label);
    echo("The value is: ".$value);

}

下面是inspector函数(和我的dInspect类)的一个例子:

http://inspect.ip1.cc

该页面的文本是西班牙语,但代码简洁,非常容易理解。

为什么不构建一个简单的函数,然后告诉它呢?

/**
 * Prints out $obj for debug
 *
 * @param any_type $obj
 * @param (string) $title
 */
function print_all( $obj, $title = false )
{
    print "\n<div style=\"font-family:Arial;\">\n";
    if( $title ) print "<div style=\"background-color:red; color:white; font-size:16px; font-weight:bold; margin:0; padding:10px; text-align:center;\">$title</div>\n";
    print "<pre style=\"background-color:yellow; border:2px solid red; color:black; margin:0; padding:10px;\">\n\n";
    var_export( $obj );
    print "\n\n</pre>\n</div>\n";
}

print_all( $aUser, '$aUser' );

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

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

使用此方法将用户变量从全局变量分离到当前的检查变量。

function get_user_var_defined () 
{
    return array_slice($GLOBALS,8,count($GLOBALS)-8);     
}

function get_var_name ($var) 
{
    $vuser = get_user_var_defined(); 
    foreach($vuser as $key=>$value) 
    {
        if($var===$value) return $key ; 
    }
}