【问题标题】:In PHP, How to Convert an Argument Name into a String在 PHP 中,如何将参数名称转换为字符串
【发布时间】:2010-10-29 23:22:46
【问题描述】:

我的目标是回显传递给函数的参数。例如,如何做到这一点?

$contact_name = 'foo';

function do_something($some_argument){
// echo 'contact_name'  .... How???
}

do_something($contact_name);

【问题讨论】:

  • 作为一名 PHP 开发人员,我必须问,你为什么需要这个?想要这样做的唯一正当理由是在调试/错误处理/等的上下文中。

标签: php string arguments


【解决方案1】:

Sander 有正确的答案,但这正是我正在寻找的东西:

$contact_name = 'foo';

function do_something($args = array(), $another_arg) {
    foreach ($args as $name => $value) {
        echo $name;
        echo '<br>'.$another_arg;
    }
}

do_something(compact(contact_name),'bar');

【讨论】:

    【解决方案2】:

    基于 PTBNL 的(绝对正确)的答案,我想出了一个更具可读性(至少我认为如此)的方法:

    /**
     * returns the name of the variable posted as the first parameter.
     * If not called from global scope, pass in get_defined_vars() as the second parameter
     *
     * behind the scenes:
     *
     *   this function only works because we are passing the first argument by reference.
     *   1. we store the old value in a known variable
     *   2. we overwrite the argument with a known randomized hash value
     *   3. we loop through the scope's symbol table until we find the known value
     *   4. we restore the arguments original value and
     *   5. we return the name of the symbol we found in the table
     */
    function variable_name( & $var, array $scope = null )
    {
        if ( $scope == null )
        {
            $scope = $GLOBALS;
        }
    
        $__variable_name_original_value = $var;
        $__variable_name_temporary_value = md5( number_format( microtime( true ), 10, '', '' ).rand() );
        $var = $__variable_name_temporary_value;
    
        foreach( $scope as $variable => $value )
        {
            if ( $value == $__variable_name_temporary_value && $variable != '__variable_name_original_value' )
            {
                $var = $__variable_name_original_value;
                return $variable;
            }
        }
        return null;
    }
    
    // prove that it works:
    
    $test = 1;
    $hello = 1;
    $world = 2;
    $foo = 100;
    $bar = 10;
    $awesome = 1;
    
    function test_from_local_scope()
    {
        $local_test = 1;
        $local_hello = 1;
        $local_world = 2;
        $local_foo = 100;
        $local_bar = 10;
        $local_awesome = 1;
    
        return variable_name( $local_awesome, get_defined_vars() );
    }
    printf( "%s\n", variable_name( $awesome, get_defined_vars() ) ); // will echo 'awesome'
    printf( "%s\n", test_from_local_scope() ); // will also echo awesome;
    

    【讨论】:

      【解决方案3】:

      直接离开 PHP.net variables 页面:

      <?php
        function vname(&$var, $scope=false, $prefix='unique', $suffix='value')
        {
          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;
        }
      ?>
      

      【讨论】:

      • 我刚刚测试了这个,它确实有效,太棒了。现在找到它的实际用途;)
      【解决方案4】:

      免责声明:仅当您将变量而不是值传递给函数时才有效,并且仅当您不在函数或类中时才有效。所以只有 GLOBAL 范围有效:)

      Good funct($var)
      Bad funct(1)
      

      你可以做到与普遍认为的相反^_^。但它涉及到一些 $GLOBALS 变量的查找技巧。

      你这样做:

      $variable_name = "some value, better if its unique";
      
      function funct($var) {
         foreach ($GLOBALS as $name => $value) {
            if ($value == $var) {
               echo $name; // will echo variable_name
               break;
            }
         }
      }
      

      这种方法不是万无一失的。因为如果两个变量具有相同的值,该函数将获取它找到的第一个变量的名称。不是你想要的:P 如果您想要变量名称的准确性,最好事先使变量值唯一

      另一种方法是像这样使用参考来准确

      $variable_name = 123;
      
      function funct(&$var) {
      
         $old = $var;
         $var = $checksum = md5(time());  // give it unique value
      
         foreach ($GLOBALS as $name => $value) {
            if ($value == $var) {
               echo $name; // will echo variable_name
               $var = $old; // reassign old value
               break;
            }
         }
      }
      

      所以完全有可能:)

      【讨论】:

      • 如果我在其中传递 (int)1 甚至都行不通(将返回 'argc'
      • 这些示例假设您传递的是变量而不是值。谢谢你提醒我,我用免责声明更新了:)
      • @ozzy,我将它作为具有该值的变量传入,即使通过引用它也没有给我任何靠近要求的“联系人姓名”(是的,我实际上正在尝试解决这个问题)跨度>
      • 现在我很感兴趣>
      • 奇怪,我测试了两者并且都完美地工作。在参考文献中,我使用的是funct($var) 而不是funct(&$var),这是它对你不起作用的一个原因。两者对我来说都很好。你确定你的测试在正确的范围内?
      【解决方案5】:
      class Someone{
        protected $name='';
        public function __construct($name){
          $this->name=$name;
        }
      
        public function doSomthing($arg){
           echo "My name is: {$this->name} and I do {$arg}";
        }
      }
      
      //in main
      $Me=new Someone('Itay Moav');
      $Me->doSomething('test');
      

      【讨论】:

        【解决方案6】:

        变量只是用于寻址内存中的值或区域的方法。您无法获取已将值传递给函数的变量名称。

        【讨论】:

          【解决方案7】:

          你不能。如果你想这样做,你还需要传递名称,例如:

          $contact_name = 'foo';
          $contact_phone = '555-1234';
          
          function do_something($args = array()) {
              foreach ($args as $name => $value) {
                  echo "$name: $value<br />";
              }
          }
          
          do_something(compact('contact_name', 'contact_phone'));
          

          【讨论】:

          • 不错,以前没用过compact。
          • 在开始创建 CakePHP 网站之前,我也从未使用过它。他们经常使用它,我看到它如何使某些函数语句更短。
          【解决方案8】:

          不可能。

          【讨论】:

          • Downvoter:对不起,你不喜欢它,但事实并非如此。接受的答案和所有其他答案都是假装你正在做 OP 要求的可爱方式,而不是实际去做的方式。我的回答和秋葵的回答是唯一准确的。
          猜你喜欢
          • 2022-11-09
          • 2021-07-11
          • 2011-12-13
          • 2017-07-19
          • 1970-01-01
          • 1970-01-01
          • 2017-09-08
          • 1970-01-01
          • 2021-04-04
          相关资源
          最近更新 更多