views:

428

answers:

8

My goal is to echo the argument passed to a function. For example, how can this be done?

$contact_name = 'foo';

function do_something($some_argument){
// echo 'contact_name'  .... How???
}

do_something($contact_name);
A: 

Not possible.

chaos
+4  A: 

You can't. If you want to do that, you need to pass the names as well, e.g:

$contact_name = 'foo';
$contact_phone = '555-1234';

function do_something($args = array()) {
    foreach ($args as $name => $value) {
        echo "$name: $value<br />";
    }
}

do_something(compact('contact_name', 'contact_phone'));
Sander Marechal
Nice, never used compact before.
Adam Backstrom
I never used it either until I started creating CakePHP websites. They use it quite a bit and I saw how it can make certain functions statements much shorter.
Sander Marechal
Thanks Sander. Works great!
A: 

Variables are just means to address values or areas in the memory. You cannot get the variable name that’s value has been passed to a function.

Gumbo
A: 

Disclaimer: this will oonly work if you pass a variable to the function, not a value, and it only works when your not in a function or a class. So only the GLOBAL scope works :)

Good funct($var)
Bad funct(1)

You can do it actually contrary to popular believe ^_^. but it involves a few lookup tricks with the $GLOBALS variable.

you do it like so:

$variable_name = "some value, better if its unique";

function funct($var) {
   foreach ($GLOBALS as $name => $value) {
      if ($value == $var) {
         echo $name; // will echo variable_name
         break;
      }
   }
}

this method is not fool proof tho. Because if two variables have the same value, the function will get the name of the first one it finds. Not the one you want :P Its best to make the variable value unique before hand if you want accuracy on variable names

Another method would be to use reference to be accurate like so

$variable_name = 123;

function funct(&$var) {

   $old = $var;
   $var = $checksum = md5(time());  // give it unique value

   foreach ($GLOBALS as $name => $value) {
      if ($value == $var) {
         echo $name; // will echo variable_name
         $var = $old; // reassign old value
         break;
      }
   }
}

so it is entirely possible :)

Ozzy
that's not even going to work if i pass (int)1 in there (will return 'argc'
Kris
well the examples assume you pass a variable and not a value. thanks for reminding me tho, ill update with a disclamer :)
Ozzy
@ozzy, i passed it in as a variable with that value, even by reference it doesn't give me anythin near the requisted 'contact_name' (yes i am actually trying to solve this)
Kris
now im intrigued >< i wrote that code from memory, ima run it now see if it works
Ozzy
Ozzy
That's an awfully hideous hack, solving a "problem" that's more likely based in a lack of understanding, than an actual problem.
Frank Farmer
A: 
class Someone{
  protected $name='';
  public function __construct($name){
    $this->name=$name;
  }

  public function doSomthing($arg){
     echo "My name is: {$this->name} and I do {$arg}";
  }
}

//in main
$Me=new Someone('Itay Moav');
$Me->doSomething('test');
Itay Moav
somehow i wonder how this is related to the question...
Kris
+1  A: 

Straight off the PHP.net variables page:

<?php
  function vname(&$var, $scope=false, $prefix='unique', $suffix='value')
  {
    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;
  }
?>
PTBNL
I just tested this and it actually works, amazing. now to find a real-world use for it ;)
Kris
A: 

Based on PTBNL's (most definately correct) answer i came up with a more readable (at least i think so) approach:

/**
 * returns the name of the variable posted as the first parameter.
 * If not called from global scope, pass in get_defined_vars() as the second parameter
 *
 * behind the scenes:
 *
 *   this function only works because we are passing the first argument by reference.
 *   1. we store the old value in a known variable
 *   2. we overwrite the argument with a known randomized hash value
 *   3. we loop through the scope's symbol table until we find the known value
 *   4. we restore the arguments original value and
 *   5. we return the name of the symbol we found in the table
 */
function variable_name( & $var, array $scope = null )
{
    if ( $scope == null )
    {
     $scope = $GLOBALS;
    }

    $__variable_name_original_value = $var;
    $__variable_name_temporary_value = md5( number_format( microtime( true ), 10, '', '' ).rand() );
    $var = $__variable_name_temporary_value;

    foreach( $scope as $variable => $value )
    {
     if ( $value == $__variable_name_temporary_value && $variable != '__variable_name_original_value' )
     {
      $var = $__variable_name_original_value;
      return $variable;
     }
    }
    return null;
}

// prove that it works:

$test = 1;
$hello = 1;
$world = 2;
$foo = 100;
$bar = 10;
$awesome = 1;

function test_from_local_scope()
{
    $local_test = 1;
    $local_hello = 1;
    $local_world = 2;
    $local_foo = 100;
    $local_bar = 10;
    $local_awesome = 1;

    return variable_name( $local_awesome, get_defined_vars() );
}
printf( "%s\n", variable_name( $awesome, get_defined_vars() ) ); // will echo 'awesome'
printf( "%s\n", test_from_local_scope() ); // will also echo awesome;
Kris
A: 

Sander has the right answer, but here is the exact thing I was looking for:

$contact_name = 'foo';

function do_something($args = array(), $another_arg) {
    foreach ($args as $name => $value) {
        echo $name;
        echo '<br>'.$another_arg;
    }
}

do_something(compact(contact_name),'bar');