Alex
Alex

Reputation: 68036

Find out parameters passed to a function

I'm trying to find out the name of the paramters that were passed to a function.

To do this I'm using debug_backtrace() to get the file and line from which the function was called.

Then open the file, read it line by line until the line that I'm looking for comes up.

$file = fopen($caller['file'], 'r' );
$line = 0;
while(($row = fgets($file)) !== false){
  $line++; 
  if($line == $caller['line']) break;
}      

fclose($file);

// $row is my line

So now i have a line like:

my_function ($var1, some_other_function($othervar1, $othervar2));

How can I extract arguments from it? I want to get an array like:

array('$var1', 'some_other_function($othervar1, $othervar2)');

Upvotes: 1

Views: 806

Answers (5)

Austin
Austin

Reputation: 6034

Take a look at func_get_args. You can use it to get an array of all values passed in to a function like so:

<?php

$args = func_get_args();
var_export($args);

?>

You can not retrieve the names of the values a function accepts in PHP.

The reasoning behind this is simple, you will never rearrange the order of your input variables. Think of this:

function foo($var1, $var2, $var3) {

You pass in what you want for $var1 in as parameter 1. You will never pass what you want for $var1 in parameter 2 or 3.

Why don't your just log your function parameters inside the function itself?

function foo($one, $two) {
    echo '$one: '. $one "\n";
    echo '$two: '. $two "\n";
}

Upvotes: 1

Filip Ros&#233;en
Filip Ros&#233;en

Reputation: 63807

The easiest method to a specific line from a file is to read it using file, though this might cause some performance overhead since it will read the whole file at once:

function func ($arg1, $arg2) 
{
  list($caller) = debug_backtrace (); 
  $file_lines   = file ($caller['file']);

  echo "function called as: " . $file_lines[$caller['line'] - 1]; 
}

$a = $b = 0;

func ($a,$b);

function called as: func ($a,$b);

There are a few issues with doing what you are doing though, for one you assume that the contents of where the calling takes place only spans across one line. If you are having lots of arguments to a function you might split it up onto several lines as in the below snippet, in which case your function won't behave as it should.

func (
  $a, $b,
  $c, $d
);

The contents printed by your function will only contain );


pending edit with a full-blown example that will "always" work

Upvotes: 1

Woss
Woss

Reputation: 1454

You can do:

function my_func ($var, $callback) {
   $args = func_get_args();
   call_user_func($callback);
   ...
}

and:

my_func('value1', 'some_other_function');

then:

$args will be ('value', 'some_other_function');

Upvotes: 1

drew010
drew010

Reputation: 69957

It's a complicated issue. Even in your example, the second parameter to the function doesn't have a name because it is the return value of a call to another function.

You may have some luck with token_get_all() to tokenize the code for you and then you can loop over the results and try to get what you need.

$tokens = token_get_all('<?php my_function($var1, some_other_function($othervar1, $othervar2)); ?>');

print_r($tokens);

Yields:

Array
(
    [0] => Array
        (
            [0] => 372
            [1] => <?php 
            [2] => 1
        )

    [1] => Array
        (
            [0] => 307
            [1] => my_function
            [2] => 1
        )

    [2] => (
    [3] => Array
        (
            [0] => 309
            [1] => $var1
            [2] => 1
        )

    [4] => ,
    [5] => Array
        (
            [0] => 375
            [1] =>  
            [2] => 1
        )

    [6] => Array
        (
            [0] => 307
            [1] => some_other_function
            [2] => 1
        )

    [7] => (
    [8] => Array
        (
            [0] => 309
            [1] => $othervar1
            [2] => 1
        )

    [9] => ,
    [10] => Array
        (
            [0] => 375
            [1] =>  
            [2] => 1
        )

    [11] => Array
        (
            [0] => 309
            [1] => $othervar2
            [2] => 1
        )

    [12] => )
    [13] => )
    [14] => ;
    [15] => Array
        (
            [0] => 375
            [1] =>  
            [2] => 1
        )

    [16] => Array
        (
            [0] => 374
            [1] => ?>
            [2] => 1
        )

)

Using the List of Parser Tokens you can loop over that array and figure out what the parameters passed to the function were. Even so, it may be too generic because your call to my_function is just a T_STRING token that the Zend Engine eventually looks for in a function table and calls the function if it exists, or throws a fatal error if it doesn't.

Upvotes: 2

solidau
solidau

Reputation: 4081

I think you're looking for get_func_args: http://php.net/manual/en/function.func-get-args.php

Upvotes: 1

Related Questions