Getting parameter names in PHP

When a function is called in PHP (and in most other languages), either the values or references to those values are passed as parameters. It is usually not possible to retrieve other information from these parameters, such as the name of the variable passed as argument.

Consider the following C code fragment, which prints both the name and the value of the variable passed to the PRINTVAR macro:

#define PRINTVAR(x) printf("%s = %d\n", #x, x)
...
int i = 3
PRINTVAR(i); // prints "i = 3"

This is of course possible because the preprocessor views the source code as nothing more than strings. It takes the string "i" which is passed to the macro and rewrites it to the code printf("...", "i", i).

In a language like PHP, you don't have a preprocessor and the name of the variable is not available like runtime. This means that if we want to obtain the variable name or the class name used when the function is called, we have to do something much more obscure.

The variable name is not available at runtime, but it is in the source. Using debug_backtrace() we can find out which file and which line called our function. We can open that file, look up that line, parse our function call out of it and determine the variable name. The example below does exactly that:

function printCallingVarname($var) {
	$backtrace = debug_backtrace();
	$caller = $backtrace[0];
	$line = getCallingLine($caller);
	$regex = '/'.__FUNCTION__.'\(([^)]*)\)/';
	preg_match($regex, $line, $matches);
	$varname = $matches[1];
	echo $varname;
}

function getCallingLine($caller)
{
	$file = $caller['file'];
	$lineno = $caller['line'];
	$fp = fopen($file, 'r');
	for ($i = 0; $i < $lineno; $i++) {
		$line = fgets($fp);
	}
	return $line;
}

printCallingVarname($a);

In line 2, we obtain a stacktrace. It contains elements which correspond with function calls. The first element corresponds with the calling of this function. In line 3 we get the information about that call and in line 4 we call our self-made function which reads the line from the file. On that line we let a regex loose which searches for printCallingVarname(...). Whatever is between the parenthesis is what we are looking for.

Of course we can find class names in a similar way:

class VarHandler {
	function printCallingClassname()
	{
		$backtrace = debug_backtrace();
		$caller = $backtrace[0];
		$line = $this->getCallingLine($caller);
		$regex = '/(\$[^-]*)->' . __FUNCTION__ .'/';
		preg_match($regex, $line, $matches);
		$varname = $matches[1];
		echo $varname;
	}
	
	function getCallingLine($caller)
	{
		$file = $caller['file'];
		$lineno = $caller['line'];
		$fp = fopen($file, 'r');
		for ($i = 0; $i < $lineno; $i++) {
			$line = fgets($fp);
		}
		return $line;
	}
}

$var = new VarHandler();
$var->printCallingClassname(); // prints "$var"

This time, our regex looks for $something->printCallingClassname.

We have shown how you can obtain the variable name of the calling function or class using debug_backtrace and reading the source. This is a dirty, slow method for something you probably don't need. If you are using this code, you probably have some problem you better solve another way.