2

I want to do something like this for simplifying logging operations. Any idea what I should put in for ?[1]? and ?[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;
}

This how I'd use the function in code (numbers are assumed to be line numbers in actual code):

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

And this is what I want to be written to the log file:

23, a = hello
25, b = bye

EDIT I converted Paul Dixon function a bit and added the result as an answer. The new form does even MORE than I originally hoped for. Thank you again guys!

5
  • Take a look at xdebug. It looks like you're trying to reinvent the rocket, that already made. Commented May 20, 2010 at 18:46
  • Col., I have tried many times to get that work on my WAMP dev machine, but it simply refuses to. Commented May 20, 2010 at 19:02
  • I don't care about SO reputation, but, down-vote without a comment saying what is wrong? That's the deed of a coward. Commented May 20, 2010 at 19:09
  • Seemed a valid question to me. Have a +1 :) Commented May 20, 2010 at 19:23
  • Indeed a valid and fine question, just what I needed. And the solution is awesome too. And I for the purpose, debugging, it is not bad at all. Commented Mar 6, 2013 at 9:04

6 Answers 6

8

This isn't something you can easily do, as the function parameter is an expression which is evaluated before the function is called. Thus, the function can only see the value of that expression, and not the expression itself.

If you really want to do this, you could use debug_backtrace to find the file and line number of the caller, extract that line from the source file, then parse out the expression from the function call. Here's a proof-of-concept:

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

Clearly nuts. But it works :) You could of course simply pass the name in along with the variable!

Sign up to request clarification or add additional context in comments.

2 Comments

oh, parsing solution is just amazing! :)
... This is very clearly a correct solution (probably the only one), but even though it is likely to only be used for logging, it makes my head hurt. Gah... WHY???
1

You might be able to do something close with Reflection. Aside from that, though, there's not much else.

1 Comment

Humm, checked it. The problem is, there looks to me to be steep learning curve. But good pointer nevertheless. Thanks.
1

I played with the function provided by Paul Dixon (accepted answer) and got it into the shape really doing what I want. This could act as a poor-man's debugger, and I hope it will be useful to someone.

Here is the function and example usage/output:

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

And here is sample usage (numbers represent line numbers in actual code):

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

The example will produce this output in the log file:

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

Comments

0

You cannot get variable name.

Though you can make it just

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

Comments

0

The problem with this is that the variable should have a unique value :(

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

Clarification: you should NOT try to do things like this... it's not recommend and there are probably better ways to do what you want.

Comments

0

I don't know if it can be done, that you get the line number of where the variable is set, what you can do:

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

So you can do this:

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

and the output will, look like this:

23, a = hello
25, b = bye

I don't believe you can get it any better. But if someone knows how to get it, i'm willing to learn

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.