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

时间:2010-05-20 18:30:48

标签: php

我想做这样的事情来简化日志记录操作。知道我应该为?[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 个答案:

答案 0 :(得分:8)

这不是你可以轻易做到的事情,因为函数参数是一个在调用函数之前计算的表达式。因此,该函数只能看到该表达式的值,而不能看到表达式本身。

如果确实想要这样做,您可以使用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);

显然坚果。但它有效:)你当然可以简单地将名称与变量一起传递!

答案 1 :(得分:1)

您可以使用Reflection做一些事情。除此之外,没有其他的东西。

答案 2 :(得分:1)

我使用了Paul Dixon提供的功能(接受了答案),并将其打造成真正做我想要的形状。这可以作为一个穷人的调试器,我希望它对某人有用。

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

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

答案 3 :(得分:0)

你不能得到变量名。

虽然你可以做到这一点

log_var("a",$a);
log_var("b",$b);

答案 4 :(得分:0)

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

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

澄清:你不应该尝试做这样的事情......不建议这样做,并且可能有更好的方法来做你想做的事。

答案 5 :(得分:0)

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

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

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