【问题标题】:How to get a variable name as a string in PHP?如何在 PHP 中将变量名作为字符串获取?
【发布时间】:2010-09-20 07:08:19
【问题描述】:

假设我有这个 PHP 代码:

$FooBar = "a string";

然后我需要这样的函数:

print_var_name($FooBar);

哪个打印:

FooBar

任何想法如何实现这一目标?这在 PHP 中是否可行?

【问题讨论】:

  • 如果你需要它来做除调试以外的任何事情,那你就做错了。你的用例是什么?
  • 好问题。我需要同样的调试。
  • +1 - 我需要它来从模型 PHP 对象自动生成 XML 或 JSON 响应。必须将对象包装在另一个名为 rootName => modelObject 的数组中只会给响应增加不必要的深度。希望这被纳入语言的运行时反射功能。
  • 我在日志功能中也需要这个。我希望能够做到以下几点: log($didTheSystemBlowUp);要出现在日志文件中,如:$didTheSystemBlowUp = '还没有,但很快';
  • 这在调用 var_dump() 时也很有用,因此当您同时调用多个变量时,您无需手动输出 var 名称来区分 vardupms 的输出。

标签: php


【解决方案1】:

我也想不出一种有效的方法,但我想出了这个。它适用于以下有限用途。

耸耸肩

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

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

【讨论】:

  • 这有效,但前提是函数 varName 与要查找的变量在同一个文件中定义。
  • 在这里你可以找到一个更好的实现,包括:stackoverflow.com/a/19788805/1069083
【解决方案2】:

您可以使用get_defined_vars() 来查找与您要查找的名称具有相同值的变量的名称。显然这并不总是有效,因为不同的变量通常具有相同的值,但这是我能想到的唯一方法。

编辑:get_defined_vars() 似乎无法正常工作,它返回 'var' 因为在函数本身中使用了 $var。 $GLOBALS 似乎有效,所以我将其更改为。

function print_var_name($var) {
    foreach($GLOBALS as $var_name => $value) {
        if ($value === $var) {
            return $var_name;
        }
    }

    return false;
}

编辑:需要明确的是,在 PHP 中没有这样做的好方法,这可能是因为您不应该这样做。可能有更好的方法来做你想做的事情。

【讨论】:

  • 啊。一直很慢;-) 想法相同,但改用 $GLOBALS 。因此,恒等比较对等于标量值 ($a = 'foo'; $b = 'foo'; assert($a === $b);) 产生真值?
  • 实际上现在我已经测试了我的代码,我的代码总是返回'var',因为它正在函数中使用。当我改用 $GLOBALS 时,它会出于某种原因返回正确的变量名。所以我将把上面的代码改成使用 $GLOBALS。
  • 在很多情况下,此代码的行为与预期不符。
  • 此代码非常不正确。检查变量是否与 VALUE 发送的变量相同是一个非常愚蠢的想法。无数变量在任何给定点都是 NULL。 Myriads 设置为 1。这太疯狂了。
  • 用 $a = 10 试试你的代码; $b = 10; print_r(print_var_name($b));
【解决方案3】:

您可能会考虑改变您的方法并使用变量变量名?

$var_name = "FooBar";
$$var_name = "a string";

那么你就可以了

print($var_name);

得到

FooBar

这是PHP manual on Variable variables的链接

【讨论】:

  • 我曾使用过一个广泛使用可变变量的系统。让我警告你,它真的很快就变臭了!
  • 大多数情况下用户想要获取一个var的名字和值。想想“function debugvar($varname)”,他打算称它为“debugvar('foo')”,所以调试将显示“foo = 123”。使用变量变量,他们将得到 'foo' 是未定义的。
  • 看看你实际在做什么。在您的示例中,您实际上创建了一个变量$FooBar,其值为a string,只需阅读您的手册即可。这是可怕的恕我直言。您永远不会为变量$FooBar 赋值,但它就在那里。 哎哟
【解决方案4】:

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

  • “变量”只是指向其他事物的符号。在 PHP 中,它在内部指向一个叫做“zval”的东西,它实际上可以同时用于多个变量,或者因为它们具有相同的值(PHP 实现了一个叫做“copy-on-write”的东西,所以$foo = $bar 没有'不需要立即分配额外的内存)或者因为它们已通过引用分配(或传递给函数)(例如$foo =&amp; $bar)。所以 zval 没有名字。
  • 当您将参数传递给函数时,您正在创建一个 变量(即使它是一个引用)。你可以传递一些匿名的东西,比如"hello",但是一旦进入你的函数,它就是你命名的任何变量。这对于代码分离是相当基础的:如果一个函数依赖于要调用的变量使用,它更像是一个goto,而不是一个适当分离的函数。
  • 全局变量通常被认为是一个坏主意。这里的很多例子都假设你想“反映”的变量可以在$GLOBALS 中找到,但这只有在你的代码结构不好并且变量没有作用于某个函数或对象的情况下才会成立。
  • 变量名称可以帮助程序员阅读他们的代码。重命名变量以更好地适应它们的用途是一种非常常见的重构实践,重点是它没有任何区别。

现在,我理解了对调试的需求(尽管一些建议的用法远不止于此),但作为一个通用的解决方案,它实际上并没有你想象的那么有用:如果你的调试函数说你的变量被调用“$file”,它仍然可以是代码中数十个“$file”变量中的任何一个,或者是一个您已称为“$filename”但传递给参数称为“$file”的函数的变量。

一条更有用的信息是在您的代码中调用调试函数的位置。由于您可以在编辑器中快速找到它,因此您可以查看自己输出的变量,甚至可以一次性将整个表达式传递给它(例如debug('$foo + $bar = ' . ($foo + $bar)))。

为此,您可以在调试函数的顶部使用这个 sn-p:

$backtrace = debug_backtrace();
echo '# Debug function called from ' . $backtrace[0]['file'] . ' at line ' . $backtrace[0]['line'];

【讨论】:

  • 已经有一些很好的答案了。所以即使面对现实,这也只是悲观。
  • @a20 所有答案都对何时可以使用以及何时会损坏提出了严格的警告; none 是从任何变量到其名称的简单查找,因为这实际上是不可能的。有些人为了调试目的做了很多时髦的反射,这很好;但是,我的观点认为你最好只输出行号并自己查找源代码行 - 或者使用像 XDebug 这样的交互式调试器。
【解决方案5】:

这正是您想要的 - 它是一个随时可用的“复制和插入”功能,可以回显给定 var 的名称:

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

【讨论】:

  • 酷,谢谢。我将 $pat 行稍微修改为 $pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i'; 这样我不关心这个调试函数被调用了什么,我得到了传递给函数的确切内容,即 $hello 或“hello”(我删除了 $ 匹配传入的变量,在同一行中)
  • 一段很棒的代码!谢谢!但是,它似乎并非在所有情况下都有效。使用 php 7.2.19 在我的 ubuntu 18.04 上测试的结果:在同一行代码上多次使用时不起作用,无论它是用于一个表达式还是单独的表达式,因为它返回最后一个变量的名称线。如果它在同一个表达式中使用但在不同的行上它可以工作。在不同行的不同表达中使用它有效。
  • 该函数也应该在没有“var_dump”的一行中 - 结合print_var_name, echo, var_dump发送输出$variable); echo ' '; var_dump($variable
  • 非常适合调试。
  • 这是一个非常有创意的解决方案。优秀的功能!另外,OP没有特别问,因为我认为他是在为这个问题隔离他的问题,但是,我认为OP也想要价值输出。因此,为了避免编写更多的客户端代码,可以将函数的最后一行替换为:echo '&lt;pre&gt;' . trim($var) . ' = ' . print_r(current(func_get_args()), true) . '&lt;/pre&gt;';,它输出 FooBar = 一个字符串,并且还包含数组。
【解决方案6】:

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

这只是检测传递的表达式的包装函数。 适用于大多数情况。 如果您在同一行代码中多次调用该函数,它将不起作用。

这很好用: die(inspect($this->getUser()->hasCredential("delete")));

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

}

这是一个实际的检查器函数(和我的 dInspect 类)示例:

http://inspect.ip1.cc

该页面中的文本为西班牙语,但代码简洁且非常易于理解。

【讨论】:

  • errrm,这不取决于您安装了 NuSpare 调试器吗?
  • 我在那里发布了这段代码的简化版本。我也修改了这个答案。它现在应该在每个 PHP5 实现上运行。
  • 这样的聪明才智是为什么我每次看到人们说“做不到”或“不可能”时都会微笑的原因,在这种情况下甚至包括拉斯穆斯本人。感谢 Sebastián 和其他可能对此答案做出贡献的人。
  • 感谢夜猫子,但我坚持认为这不是防弹的(如答案所述,如果我的“inspect()”函数在一行中被多次调用,它将失败!)。我永远不会在生产中使用它。它仅适用于永远不应到达生产服务器的调试检查器功能。
【解决方案7】:

PHP.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

【讨论】:

  • 如何以数组形式获取当前作用域?
  • 不错!对我来说,唯一缺少的是break;,当在 foreach 中发现相等时,我做了可用的基本结构来自动获取 var_name (如果在函数内部定义)。如果您经常复制粘贴或有更好的想法来改进它,请使用variable_name( $variable, ( empty(__FUNCTION__) ? false : get_defined_vars() ) );
  • 这可能是完成这项工作的最快和最干净的方法,调试可能包括性能问题。该函数应该直接在 foreach 循环中返回,而不是仅仅在没有中断的情况下进行分配。鉴于 GLOBALS 可能很大,这可以极大地提高性能。
【解决方案8】:

来自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 - 用法

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

【讨论】:

    【解决方案9】:

    许多回复质疑这是否有用。但是,获取变量的引用可能非常有用。尤其是在对象和 $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
    

    【讨论】:

      【解决方案10】:

      改编自上面针对许多变量的答案,具有良好的性能,只需一次 $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
              )
      
      )
      

      【讨论】:

        【解决方案11】:

        您可以使用 compact() 来实现这一点。

        $FooBar = "a string";
        
        $newArray = compact('FooBar');
        

        这将创建一个以变量名作为键的关联数组。然后,您可以使用所需的键名循环遍历数组。

        foreach($newarray as $key => $value) {
            echo $key;
        }
        

        【讨论】:

        • 很酷,但您必须知道变量的名称才能使用它。 OP 正在寻求以编程方式确定变量名称。
        【解决方案12】:

        如果变量是可互换的,您必须有逻辑某处来确定使用哪个变量。您需要做的就是将变量名称放在 $variable 中,同时执行其他所有操作。

        我认为我们都很难理解您需要这个做什么。示例代码或对您实际尝试执行的操作的解释可能会有所帮助,但我怀疑您的方式,方式想太多了。

        【讨论】:

          【解决方案13】:

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

          我有一个函数 cacheVariable($var)(好的,我有一个函数 cache($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));
          }
          

          但这也失败了...... :(

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

          所以,我想要的是一个函数,它可以获取变量的原始名称,因为它被传递给函数。在函数内部,我似乎无法知道这一点。在上面的第二个示例中通过引用传递 get_defined_vars() 对我有所帮助(感谢 Jean-Jacques Guegan 的想法)。后一个函数开始工作,但它仍然只返回局部变量(“变量”,而不是“颜色”)。

          我还没有尝试过结合使用 get_func_args() 和 get_func_arg()、${}-constructs 和 key(),但我想它也会失败。

          【讨论】:

          • 最基本的问题是您将传递给函数,而不是变量。变量是临时的并且特定于它们的范围。通常,变量名可能不是您要在其下缓存值的键,而且您通常会将其恢复为不同命名的变量(就像您在示例中所做的那样)。如果您实在懒得重复键名来记住变量,请使用cacheVariable(compact('color'))
          【解决方案14】:

          我有这个:

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

          我更喜欢这个:

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

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

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

          【讨论】:

            【解决方案15】:

            这是我基于Jeremy Ruten的解决方案

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

            【讨论】:

              【解决方案16】:

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

              为数组键使用变量名:

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

              当您想获取变量名时,请使用array_keys($vars),它将返回一个数组,其中包含在您的$vars 数组中使用的变量名作为键。

              【讨论】:

              • 比更常用的变量声明方法慢得多。
              【解决方案17】:

              我就是这样做的

              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
              

              注意:由于array_search$GLOBALS 中的错误,某些 PHP 7 版本将无法正常工作,但所有其他版本都可以正常工作。

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

              【讨论】:

                【解决方案18】:

                PHP 中没有可以输出变量名称的预定义函数。但是,您可以使用get_defined_vars() 的结果,它返回范围内定义的所有变量,包括名称和值。这是一个例子:

                <?php
                    // Function for determining the name of a variable
                    function getVarName(&$var, $definedVars=null) {
                        $definedVars = (!is_array($definedVars) ? $GLOBALS : $definedVars);
                        $val = $var;
                        $rand = 1;
                        while (in_array($rand, $definedVars, true)) {
                            $rand = md5(mt_rand(10000, 1000000));
                        }
                        $var = $rand;
                         
                        foreach ($definedVars as $dvName=>$dvVal) {
                            if ($dvVal === $rand) {
                                $var = $val;
                                return $dvName;
                            }
                        }
                         
                        return null;
                    }
                 
                    // the name of $a is to be determined.   
                    $a = 1;
                     
                    // Determine the name of $a
                    echo getVarName($a);
                ?>
                

                阅读更多How to get a variable name as a string in PHP?

                【讨论】:

                  【解决方案19】:

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

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

                  【讨论】:

                    【解决方案20】:

                    我一直在寻找这个,但只是决定把名字传进去,反正我通常在剪贴板中有这个名字。

                    function VarTest($my_var,$my_var_name){
                        echo '$'.$my_var_name.': '.$my_var.'<br />';
                    }
                    
                    $fruit='apple';
                    VarTest($fruit,'fruit');
                    

                    【讨论】:

                      【解决方案21】:

                      我知道这是旧的并且已经回答但我实际上正在寻找这个。我发布这个答案是为了节省人们一些时间来完善一些答案。

                      选项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 为空或 null,它将打印它找到的第一个空或 null 字符串的名称。

                      可以这样使用:

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

                      【讨论】:

                        【解决方案22】:

                        其他用途:

                        耸耸肩

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

                        【讨论】:

                          【解决方案23】:

                          使用它从全局中分离用户变量以检查当前变量。

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

                          【讨论】:

                          • @IMSoP 从print implode( ' ', array_keys( $GLOBALS )); 的输出来看,它看起来像是对“默认”全局变量数量的错误假设。在我的系统上有七个超全局变量:$_GET、$_POST、$_COOKIE、$_FILES、$_ENV、$_REQUEST、$_SERVER。还有 argv 和 argc。所以偏移量应该是 9。指定第三个参数(长度)是没有意义的,因为无论如何默认只是运行到数组的末尾。
                          【解决方案24】:

                          这可能被认为是又快又脏,但我个人的偏好是使用这样的函数/方法:

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

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

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

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

                          【讨论】:

                          • 这是变量的值,而不是变量的名称。正如在其他地方指出的那样,该名称不能跨函数边界移植。
                          • 减一,因为这个函数实际上只返回 trim($var);
                          【解决方案25】:

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

                              $variableName = "ajaxmint";
                          
                              echo getVarName('$variableName');
                          
                              function getVarName($name) {
                                  return str_replace('$','',$name);
                              }
                          

                          【讨论】:

                          • 因为 OP 不知道变量名。如果他这样做了,他就不需要getVarName() 函数。 ;-)
                          • 这不会将变量的名称作为字符串返回,因为'$variableName' 已经是字符串,而不是变量。如果你能用getVarName($variableName); 做这个技巧,你会得到一个支持:)
                          【解决方案26】:

                          我真的看不到用例...如果您输入 print_var_name($foobar) 代替输入 print("foobar") 有什么困难(和不同)?

                          因为即使你要在函数中使用它,你也会得到变量的本地名称...

                          无论如何,这里是reflection manual,以防万一那里有你需要的东西。

                          【讨论】:

                          • Print("foobar") 不会处理其他变量。
                          • 用例:您在代码中几乎没有调试点返回转储相同的值。你怎么知道哪个是第一个被处决的?打印标签非常有用。
                          • 那你还没有做足够的编程。我遇到的大多数语言都有一些方法可以做到这一点,通常很简单。
                          • @b01 我已经做了很多。我完全知道有许多语言允许这样做,但这本身并没有多大意义。许多语言提供了一些轻松执行 goto 的方法,这并不意味着您应该使用它来避免编写适当的流控制。在我看来,这是一个类似的案例。我不怀疑存在合理的案例,这就是为什么我想知道它的正确用例。
                          猜你喜欢
                          • 1970-01-01
                          • 2013-08-27
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2019-08-28
                          相关资源
                          最近更新 更多