tags:

views:

2695

answers:

14

Say i have this PHP code:

$FooBar = "a string";

i then need a function like this:

print_var_name($FooBar);

which prints:

FooBar

Any Ideas how to achieve this? Is this even possible in PHP?

A: 

What are the possible different ways that you can get that variable ? You can just do this ;)

print "FooBar"
hayalci
And if the variable is interchangable?
Gary Willoughby
What do you mean by "interchangable"? Can you show an example?
troelskn
+2  A: 

I really fail to see the use case... If you will type print_var_name($foobar) what's so hard (and different) about typing print("foobar") instead?

Because even if you were to use this in a function, you'd get the local name of the variable...

In any case, here's the reflection manual in case there's something you need in there.

Vinko Vrsalovic
Print("foobar") will not handle other vars.
Gary Willoughby
Yes, so? you'll still pass it to the function...
Vinko Vrsalovic
+7  A: 

You could use get_defined_vars() to find the name of a variable that has the same value as the one you're trying to find the name of. Obviously this will not always work, since different variables often have the same values, but it's the only way I can think of to do this.

Edit: get_defined_vars() doesn't seem to be working correctly, it returns 'var' because $var is used in the function itself. $GLOBALS seems to work so I've changed it to that.

function print_var_name($var) {
    foreach($GLOBALS as $var_name => $value) {
        if ($value === $var) {
            return $var_name;
        }
    }

    return false;
}

Edit: to be clear, there is no good way to do this in PHP, which is probably because you shouldn't have to do it. There are probably better ways of doing what you're trying to do.

yjerem
Ahh. Been to slow ;-) Thought the same, but using $GLOBALS instead. So the identity comparison yields true for equals scalar values ($a = 'foo'; $b = 'foo'; assert($a === $b);)?
Argelbargel
Actually now that I've tested my code, my code always returned 'var' because it's being used in the function. When I use $GLOBALS instead, it returns the correct variable name for some reason. So I'll change the above code to use $GLOBALS.
yjerem
Yup, i realised but get_defined_vars() was enough ta.
Gary Willoughby
There are lots of cases where this code won't behave as expected.
troelskn
This code is HORRIBLY incorrect. Checking to see f the variable is the same as the one that's sent over by VALUE is a very dumb idea. Myriads of variables are NULL at any given point. Myriads are set to 1. This is just crazy.
Alex
A: 

Use an array.

orlandu63
+1  A: 

If the variable is interchangable, you must have logic somewhere that's determining which variable gets used. All you need to do is put the variable name in $variable within that logic while you're doing everything else.

I think we're all having a hard time understanding what you're needing this for. Sample code or an explanation of what you're actually trying to do might help, but I suspect you're way, way overthinking this.

ceejayoz
Or underthinking...
Vinko Vrsalovic
Heh, there's that.
ceejayoz
+4  A: 

You might consider changing your approach and using a variable variable name?

$var_name = "FooBar";
$$var_name = "a string";

then you could just

print($var_name);

to get

FooBar

Here's the link to the PHP manual on Variable variables

I have worked with a system that used variable variables extensively. Let me warn you, it gets really smelly really fast!
Icode4food
+5  A: 

I couldn't think of a way to do this efficiently either but I came up with this. It works, for the limited uses below.

shrug

<?php

function varName( $v ) {
    $trace = debug_backtrace();
    $vLine = file( __FILE__ );
    $fLine = $vLine[ $trace[0]['line'] - 1 ];
    preg_match( "#\\$(\w+)#", $fLine, $match );
    print_r( $match );
}

$foo = "knight";
$bar = array( 1, 2, 3 );
$baz = 12345;

varName( $foo );
varName( $bar );
varName( $baz );

?>

// Returns
Array
(
    [0] => $foo
    [1] => foo
)
Array
(
    [0] => $bar
    [1] => bar
)
Array
(
    [0] => $baz
    [1] => baz
)

It works based on the line that called the function, where it finds the argument you passed in. I suppose it could be expanded to work with multiple arguments but, like others have said, if you could explain the situation better, another solution would probably work better.

Nick Presta
A: 

I actually have a valid use case for this.

I have a function cacheVariable($var) (ok, I have a function cache($key, $value), but I'd like to have a function as mentioned).

The purpose is to do:

$colour = 'blue';
cacheVariable($colour);

...

// another session

...

$myColour = getCachedVariable('colour');

I have tried with

function cacheVariable($variable) {
   $key = ${$variable}; // This doesn't help! It only gives 'variable'.
   // do some caching using suitable backend such as apc, memcache or ramdisk
}

I have also tried with

function varName(&$var) {
   $definedVariables = get_defined_vars();
   $copyOfDefinedVariables = array();
   foreach ($definedVariables as $variable=>$value) {
      $copyOfDefinedVariables[$variable] = $value;
   }
   $oldVar = $var;
   $var = !$var;
   $difference = array_diff_assoc($definedVariables, $copyOfDefinedVariables);
   $var = $oldVar;
   return key(array_slice($difference, 0, 1, true));
}

But this fails as well... :(

Sure, I could continue to do cache('colour', $colour), but I'm lazy, you know... ;)

So, what I want is a function that gets the ORIGINAL name of a variable, as it was passed to a function. Inside the function there is no way I'm able to know that, as it seems. Passing get_defined_vars() by reference in the second example above helped me (Thanks to Jean-Jacques Guegan for that idea) somewhat. The latter function started working, but it still only kept returning the local variable ('variable', not 'colour').

I haven't tried yet to use get_func_args() and get_func_arg(), ${}-constructs and key() combined, but I presume it will fail as well.

Aron Cederholm
The very basic problem is that you're passing **values** into functions, not **variables**. Variables are temporary and particular to their scope. Often the variable name may not be the key you want to cache the value under, and often you'll restore it to a differently named variable anyway (as you do in your example). If you're really too lazy to repeat the name of the key to remember the variable by, use `cacheVariable(compact('color'))`.
deceze
A: 

I think the easiest way is..

$a = 'A';
$b = 'B';
$c = '999';

function printVars($arr,$delimeter = ': ',$separator = "\n") {
  foreach($arr as $v) {
    global $$v;
    echo $v.$delimeter.$$v.$separator;
  }
}
elmysnail
+2  A: 
Sebastián Grignoli
A: 

I have this:

  debug_echo(array('$query'=>$query, '$nrUsers'=>$nrUsers, '$hdr'=>$hdr));

I would prefer this:

  debug_echo($query, $nrUsers, $hdr);

The existing function displays a yellow box with a red outline and shows each variable by name and value. The array solution works but is a little convoluted to type when it is needed.

That's my use case and yes, it does have to do with debugging. I agree with those who question its use otherwise.

Will Fastie
+2  A: 

Also see: http://www.php.net/manual/en/language.variables.php#49997

Castro
A: 

I'm looking for exact solution to assign a variable name into other variable. The solution @shrug mentioned would be fine, but... it opens file within a file (too much haystack). If current file is big, and we have N-calls for check variable name we will soon run out of memory.

To explain why I need it:

I want to assign PHP variable to a template system. Standard method is assign('tplVarName', $mVar);

90% of situations tplVarName is same name as PHP variable (name, not value) so it would be convenient to call just:

quickAssign($mVar) and the method will get name of $mVar as string (mVar), assign it to $sTplVar and call assign($sTplVar, $mVar);

(method name is an example it could be called qa() or sth)

Solver1
I don't think it's possible, and it's prone to errors (the var name detection will not work on 100% of the cases), so my advice would be: don´t do it that way, just hit the extra keys.
Sebastián Grignoli
+1  A: 

Lucas on PHP.net provided a reliable way to check if a variable exists. In his example, he iterates through a copy of the global variable array (or a scoped array) of variables, changes the value to a randomly generated value, and checks for the generated value in the copied array.

function variable_name( &$var, $scope=false, $prefix='UNIQUE', $suffix='VARIABLE' ){
    if($scope) {
        $vals = $scope;
    } else {
        $vals = $GLOBALS;
    }
    $old = $var;
    $var = $new = $prefix.rand().$suffix;
    $vname = FALSE;
    foreach($vals as $key => $val) {
        if($val === $new) $vname = $key;
    }
    $var = $old;
    return $vname;
}

Then try:

$a = 'asdf';
$b = 'asdf';
$c = FALSE;
$d = FALSE;

echo variable_name($a); // a
echo variable_name($b); // b
echo variable_name($c); // c
echo variable_name($d); // d

Be sure to check his post on PHP.net: http://php.net/manual/en/language.variables.php

Workman
How do you obtain the current scope in array form?
Sebastián Grignoli