83457

PHP function: find argument's variable name, and function calls line number

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

<strong>EDIT</strong> 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!

Answer1:

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!

Answer2:

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

Answer3:

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

Answer4:

You cannot get variable name.

Though you can make it just

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

Answer5:

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.

Answer6:

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

Recommend

  • To improve login code in PHP by Sessions
  • Request map direct me to Login page in Grails
  • Fastest way to save/load data.table
  • R matching more than 2 conditions and return the response value
  • Issue with SVN Commit for certain File Extension
  • Furthest-point Voronoi diagram in Java
  • Why is `;;` giving me a syntax error in utop?
  • smarty nested if condition is not working properly?
  • LINQ join with filter criteria
  • Double dispatch in Java example
  • can variables be set randomly when declaring them again?
  • NSIS decompiler
  • Get the number 18437736874454810627
  • Getting the scrolling offset when storing coordinates
  • JSR-330 support in Picocontainer : @Inject … @Named(\"xxx)
  • Insert new calendar with SyncAdapter- Calendar API Android
  • Ensure fsync did its job
  • How to define and use opencv mat of user type
  • Allowing both email and username for authentication
  • Get one-time binding to work for ng-if
  • Cassandra Data Model
  • How do you troubleshoot character encoding problems?
  • jQuery tmpl and DataLink beta
  • Jquery - Jquery Wysiwyg return html as a string
  • php design question - will a Helper help here?
  • Arrays break string types in Julia
  • SQL merge duplicate rows and join values that are different
  • AngularJs get employee from factory
  • WPF Applying a trigger on binding failure
  • Proper way to use connect-multiparty with express.js?
  • How can I get HTML syntax highlighting in my editor for CakePHP?
  • How to set the response of a form post action to a iframe source?
  • coudnt use logback because of log4j
  • Getting Messege Twice Using IMvxMessenger
  • Java static initializers and reflection
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Authorize attributes not working in MVC 4
  • Django query for large number of relationships
  • How can i traverse a binary tree from right to left in java?
  • Python/Django TangoWithDjango Models and Databases