代码之家  ›  专栏  ›  技术社区  ›  Majid Fouladpour

php函数:查找参数的变量名,函数调用行号

php
  •  2
  • Majid Fouladpour  · 技术社区  · 14 年前

    我想做些类似的事情来简化日志操作。知道我该穿什么吗 ?[1]? ?[2]? ?

    function log_var($var) {
      $line = ?[1]?;
      $var_name = ?[2]?;
    
      $line--;
    
      $filepath = 'log-' . date('Y-m-d'). '.txt';
      $message  = "$line, $var_name = $var\n";
      $fp = fopen($filepath, "a");
      fwrite($fp, $message);
      fclose($fp);
      @chmod($filepath, 0666);
      return TRUE;
    }
    

    这就是我在代码中使用函数的方式(假设数字是实际代码中的行号):

    23  $a = 'hello';
    24  log_var($a);
    25  $b = 'bye';
    26  log_var($b);
    

    这就是我想要写入日志文件的内容:

    23, a = hello
    25, b = bye
    

    编辑 我对paul dixon函数进行了一点转换,并将结果作为答案添加。新的表格比我原来希望的还要多。再次感谢你们!

    6 回复  |  直到 14 年前
        1
  •  8
  •   Paul Dixon    14 年前

    这不是一件容易做的事情,因为函数参数是一个表达式,在调用函数之前对其进行计算。因此,函数只能看到表达式的值,而不能看到表达式本身。

    如果你 真正地 想这样做,你可以用 debug_backtrace 要查找调用方的文件和行号,请从源文件中提取该行,然后从函数调用中解析表达式。以下是概念证明:

    function dump($value)
    {
        $trace=debug_backtrace();
        $expr="<unknown>";
        if (isset($trace[0]['file']))
        {
            $lines=file($trace[0]['file']);
            $line=$lines[$trace[0]['line']-1];
            $expr=$line;
            $expr=preg_replace('/\s*dump\(/i','', $expr);
            $expr=preg_replace('/\);\s*/', '', $expr);
    
        }
    
        echo "$expr is $value\n";
    }
    
    //examples...
    $a=10;
    dump($a);
    
    dump($a+10);
    

    显然是坚果。但是它起作用了:)当然,您可以简单地将名称与变量一起传递!

        2
  •  1
  •   Amber    14 年前

    你也许能做些近在咫尺的事 Reflection . 不过,除此之外,其他的就不多了。

        3
  •  1
  •   Jonathan Dumaine    14 年前

    我发挥了保罗狄克逊(公认的答案)提供的功能,并使它的形状真正做我想做的。这可以充当一个穷人的调试器,我希望它对某些人有用。

    以下是函数和示例用法/输出:

    function dump($value)
    {
        $trace=debug_backtrace();
    
        $expr="<unknown>";
        if (isset($trace[0]['file']))
        {
            $myline = $trace[0]['line'];
            $myline--;
            $lines=file($trace[0]['file']);
            $line=$lines[$trace[0]['line']-1];
            $expr=$line;
            $expr=preg_replace('/\s*dump\(/i','', $expr);
            $expr=preg_replace('/\);\s*/', '', $expr);
        }
    
        $handle = @fopen(__FILE__, "r");
        if ($handle) {
            for ($l=1; $l < $myline+1; $l++) {
                $buffer = fgets($handle);
            }
        }
        fclose($handle);
    
        $message = "$myline \t $buffer \t $expr = $value \n\n";
        $filepath = 'log.txt';
        $fp = fopen($filepath, "a");
        fwrite($fp, $message);
        fclose($fp);
        @chmod($filepath, 0666);
        return TRUE;    
    }
    

    下面是示例用法(数字代表实际代码中的行号):

    41 //examples...
    42 $a='hello';
    43 dump($a);
    44
    45 $b = 'bye';
    46 dump($b);
    47
    48 $c = date('y-m-d');
    49 dump($c);
    50
    51 $c = $a . ' and then ' . $b;
    52 dump($c);
    

    示例将在日志文件中生成此输出:

    42  $a='hello';
        $a = hello
    
    45  $b = 'bye';
        $b = bye
    
    48  $c = date('y-m-d');
        $c = 10-05-20
    
    51  $c = $a . ' and then ' . $b;
        $c = hello and then bye
    
        4
  •  0
  •   Your Common Sense Juan Carlos Alvez Balbastro    14 年前

    无法获取变量名。

    尽管你能做到

    log_var("a",$a);
    log_var("b",$b);
    
        5
  •  0
  •   Cristian    14 年前

    问题是变量应该有一个唯一的值:(

    function log_var($var, $line) {
      $var_name = 'unknown';
      foreach($GLOBALS as $var_name => $value)
        if ($value === $var)
          $var_name = $var_name;
    
      $line--;
    
      $filepath = 'log-' . date('Y-m-d'). '.txt';
      $message  = "$line, $var_name = $var\n";
      $fp = fopen($filepath, "a");
      fwrite($fp, $message);
      fclose($fp);
      @chmod($filepath, 0666);
      return TRUE;
    }
    
    $a = 'hello';
    log_var($a, __LINE__);
    

    澄清:你不应该尝试这样做…这是不推荐的,可能还有更好的方法来做你想做的。

        6
  •  0
  •   jigfox    14 年前

    我不知道是否可以这样做,你得到变量设置位置的行号,你能做什么:

    function log_var($var, $var_name) {
      $backtrace = debug_backtrace();
      $line = $backtrace[0]['line']; // get's the line of the call for log_var
    
      $line--;
    
      $filepath = 'log-' . date('Y-m-d'). '.txt';
      $message  = "$line, $var_name = $var\n";
      $fp = fopen($filepath, "a");
      fwrite($fp, $message);
      fclose($fp);
      @chmod($filepath, 0666);
      return TRUE;
    }
    

    所以你可以这样做:

    23  $a = 'hello';
    24  log_var($a,'$a');
    25  $b = 'bye';
    26  log_var($b,'$b');
    

    输出结果如下:

    23, a = hello
    25, b = bye
    

    我不相信你能做得更好。但是如果有人知道如何得到它,我愿意学习