Переменные переменных

Иногда бывает удобно иметь переменными имена переменных. То есть, имя переменной, которое может быть определено и изменено динамически. Обычная переменная определяется примерно таким выражением:

$a = 'hello';

Переменная переменной берет значение переменной и рассматривает его как имя переменной. В вышеприведенном примере hello может быть использовано как имя переменной при помощи двух знаков доллара. То есть:

$$a = 'world';

Теперь в дереве символов PHP определены и содержатся две переменные: $a, содержащая "hello", и $hello, содержащая "world". Таким образом, выражение

echo "$a ${$a}";

выведет то же, что и

echo "$a $hello";

то есть, они оба выведут: hello world.

Для того чтобы использовать переменные переменных с массивами, вы должны решить проблему двусмысленности. То есть, если вы напишете $$a[1], обработчику необходимо знать, хотите ли вы использовать $a[1] в качестве переменной, либо вам нужна как переменная $$a, а затем ее индекс [1]. Синтаксис для разрешения этой двусмысленности таков: ${$a[1]} для первого случая и ${$a}[1] для второго.

К свойствам класса также можно получить доступ динамически. Переменное имя свойства будет разрешено в том контексте, в котором произойдет вызов к нему. Например, в случае выражения $foo->$bar, локальная область видимости будет просканирована на наличие переменной $bar, значение которой будет использовано в качестве имени свойства объекта $foo. Это также работает и в том случае, если $bar осуществляет доступ к элементу массива.

Фигурные скобки могут также использоваться, чтобы четко разграничить имя свойства. Они наиболее полезны при получении доступа к значениям внутри свойства, которое содержит массив, когда имя свойства состоит из нескольких частей, либо когда имя свойства содержит символы, которые иначе не действительны (например, из функции json_decode() или из SimpleXML).

Пример #1 Пример переменного имени свойства

class foo {
    var $bar = 'I am bar.';
    var $arr = array('I am A.', 'I am B.', 'I am C.');
    var $r   = 'I am r.';
}
$foo = new foo();
$bar = 'bar';
$baz = array('foo', 'bar', 'baz', 'quux');
echo $foo->$bar . "\n";
echo $foo->$baz[1] . "\n";
$start = 'b';
$end   = 'ar';
echo $foo->{$start . $end} . "\n";
$arr = 'arr';
echo $foo->$arr[1] . "\n";
echo $foo->{$arr}[1] . "\n";

Результат выполнения данного примера:


I am bar.
I am bar.
I am bar.
I am r.
I am B.

Внимание

Пожалуйста, обратите внимание, что переменные переменных не могут использоваться с Суперглобальными массивами PHP. Переменная $this также является особой, на нее нельзя ссылаться динамически.


User Contributed Notes 46 notes



16
userb at exampleb dot org3 years ago
  //You can even add more Dollar Signs
  $Bar = "a";
  $Foo = "Bar";
  $World = "Foo";
  $Hello = "World";
  $a = "Hello";
  $a; //Returns Hello
  $$a; //Returns World
  $$$a; //Returns Foo
  $$$$a; //Returns Bar
  $$$$$a; //Returns a
  $$$$$$a; //Returns Hello
  $$$$$$$a; //Returns World
  //... and so on ...//


7
mason3 years ago
class Foo {
   public function hello() {
      echo 'Hello world!';
   }
}
$my_foo = 'Foo';
$a = new $my_foo();
$a->hello(); //prints 'Hello world!'


3
Anonymous8 years ago
// Given these variables ...
$nameTypes    = array("first", "last", "company");
$name_first   = "John";
$name_last    = "Doe";
$name_company = "PHP.net";
// Then this loop is ...
foreach($nameTypes as $type)
  print ${"name_$type"} . "\n";
// ... equivalent to this print statement.
print "$name_first\n$name_last\n$name_company\n";


4
nils dot rocine at gmail dot com1 year ago
class Foo 
{ 
    public function __construct() 
    { 
        echo "I'm a real class!" . PHP_EOL;
    }
}
$class = 'Foo';
$instance = new $class;


3
php at ianco dot co dot uk4 years ago
// $variable-name = 'parse error';
// You can't do that but you can do this:
$a = 'variable-name';
$$a = 'hello';
echo $variable-name . ' ' . $$a; // Gives     0 hello


2
nullhility at gmail dot com5 years ago
${date("M")} = "Worked";
echo ${date("M")};


2
Nathan Hammond5 years ago
$_POST['asdf'] = 'something';
function test() {
    // NULL -- not what initially expected
    $string = '_POST';
    var_dump(${$string});
    // Works as expected
    var_dump(${'_POST'});
    // Works as expected
    global ${$string};
    var_dump(${$string});
}
// Works as expected
$string = '_POST';
var_dump(${$string});
test();


2
craigmorey at gmail dot com5 years ago
$config['modules']['module_events']['settings']['template']['name'] = 'List Page';


2
chrisNOSPAM at kampmeier dot net12 years ago
$varname = "foo";
$foo = "bar";
print $$varname;  // Prints "bar"
print "$$varname";  // Prints "$foo"
print "${$varname}"; // Prints "bar"


1
Omar Juvera2 years ago
$city = 'New York';
$var_container = 'city'; //$var_container will store the variable $city 
echo "CONTAINER's var: " . $var_container;
echo "<br />";
echo "CONTAINER's value: " . $$var_container;
echo "<br />";
echo "VAR city: " . $city;


1
dlorre at yahoo dot com3 years ago
$tab = array("one", "two", "three") ;
$a = "tab" ;
$$a[] ="four" ; // <==== fatal error
print_r($tab) ;


1
aditeojr at yahoo dot co dot uk4 years ago
function GetInputString($name, $default_value = "", $format = "GPCS")
    {
        //order of retrieve default GPCS (get, post, cookie, session);
        $format_defines = array (
        'G'=>'_GET',
        'P'=>'_POST',
        'C'=>'_COOKIE',
        'S'=>'_SESSION',
        'R'=>'_REQUEST',
        'F'=>'_FILES',
        );
        preg_match_all("/[G|P|C|S|R|F]/", $format, $matches); //splitting to globals order
        foreach ($matches[0] as $k=>$glb)
        {
            if ( isset ($GLOBALS[$format_defines[$glb]][$name]))
            {    
                return $GLOBALS[$format_defines[$glb]][$name];
            }
        }
       
        return $default_value;
    }


2
fabio at noc dot soton dot ac dot uk8 years ago
$var = "ciao";
static $$var = 0;


1
j3nda at fv dot cz5 years ago
class __info {
  private $__info=array();
  public function __s($value=null, $id='')
    {
        if ($id == '')
            return false;
        $id='[\''.$id.'\']';
        for ($i=2, $max=func_num_args(), $args=func_get_args(); $i<$max; $i++)
            $id.='[\''.$args[$i].'\']';
        eval('
            if (isset($this->__info'.$id.')) {
                // debug || vyjimka
            }
            $this->__info'.$id.'=$value;
        ');
        return true;
    }
  public function __g($id)
    {
        $uid='';
        for ($i=0, $max=func_num_args(), $args=func_get_args(); $i<$max; $i++)
            $uid.="[\'".$args[$i]."\']";
        return eval('
            if (isset($this->__info'.$uid.')) {
                return $this->__info'.$uid.';
            } else {
                return false;
            }
            // debug || vyjimka
        ');
        return false;
    }


1
correojulian33-php at yahoo dot es6 years ago
class pp{
   var $prop1=1,$prop2=2,$prop3=array(3,4,5);
   function fun1(){
      $vars=get_class_vars('pp');
      while(list($var,$value)=each($vars)){
               $ref=& $this->$var;
               $ref=$_GET[$var];
      } // while
      var_dump($this);
   }
}
$_GET['prop1']="uno";
$_GET['prop2']="dos";
$_GET['prop3']=array('tres','cuatro','cinco','seis');
$p=new pp();
$p->fun1();


1
the_tevildo at yahoo dot com6 years ago
function indirect ($var, $value)     // Replaces $$var = $value
{
   $var_data = $explode($var, ':');
   if (isset($var_data[1]))
   {
      ${$var_data[0]}[$var_data[1]] = $value;
   }
   else
   {
      ${$var_data[0]} = $value;
   }
}
$temp_array = array_fill(0, 4, 1);
$temp_var = 1;
$int_var_list = array('temp_array[2]', 'temp_var');
while (list($key, $var_name) = each($int_var_list))
{
   //  Doesn't work - creates scalar variable called "$temp_array[2]" 
   $$var_name = 0;
}
var_dump($temp_array);
echo '<br />';
var_dump($temp_var);
echo '<br />';
//  Does work!
$int_var_list = array('temp_array:2', 'temp_var');
while (list($key, $var_name) = each($int_var_list))
{
   indirect($var_name, 2);
}
var_dump($temp_array);
echo '<br />';
var_dump($temp_var);
echo '<br />';


1
Sinured6 years ago
define('ONE', 1);
function one() {
    return 1;
}
$one = 1;
${"foo$one"} = 'foo';
echo $foo1; // foo
${'foo' . ONE} = 'bar'; 
echo $foo1; // bar
${'foo' . one()} = 'baz';
echo $foo1; // baz


1
mot at tdvniikp dot ru7 years ago
function abc() {
    $context = '_SESSION';
    global $$context;
    if(isset($$context)) {
        var_dump($$context);
    }
}
abc();


1
rafael at fuchs inf br8 years ago
define("TEST","Fuchs");
$Fuchs = "Test";
echo TEST . "<br />";
echo ${TEST};


1
Shawn Beltz8 years ago
$foo = "this is foo.";
$ref = "foo";
print $$ref;
# prints "this is foo."
$foo[1]['a_z'] = "this is foo[1][a_z].";
$ref = "foo[1][a_z]";
print $$ref;
# Doesn't print anything!
$foo = "this is foo.";
$ref = "foo";
$erf = eval("return \$$ref;");
print $erf;
# prints "this is foo."
$foo[1]['a_z'] = "this is foo[1][a_z].";
$ref = "foo[1][a_z]";
$erf = eval("return \$$ref;");
print $erf;
# prints "this is foo[1][a_z]."


0
Aycan Yat1 month ago
    function setvar($n,$v){global$$n;if(!isset($$n))$$n=$v;}


0
coviex at gmail dot com3 months ago
$he = 'loves';
$loves = 'you';
$you = 'he';
echo $$$he." ".$$$$he." ".$$he; 
 
0 
 cgray at metamedia dot us ¶4 months ago
 Returning values from a multidimensional array based using variable variables
and infinite key depth
I banged my head against this but could not find a way in language structure or
in functions to retreive a value from a multidimensional array where the key
path is known as a variable string. I considered some sort of recursive
function, but it seemed cumbersome for what should be a one-liner.
My solution uses eval() to return the array value:
<?php
$geolocation = array("ip"=>"127.0.0.1", "location" => array("city" =>
"Knoxville", "state_province" => "TN", "country" => "USA"));
print_r($geolocation); // Array ( [ip] => 127.0.0.1 [location] => Array ( [city]
=> Knoxville [state_province] => TN [country] => USA ) )
// typical use of variable variables
$key = "ip";
$result = $geolocation[$key];
print_r($result); // 127.0.0.1
$key = "location"; // another typical use of variable variables
$result = $geolocation[$key];
print_r($result); // Array ( [city] => Knoxville [state_province] => TN
[country] => USA )
// but how do we go deeper? this does NOT work
$key = "location['city']";
// $result = $geolocation[$key]; // Notice: Undefined index: location['city']
// print_r($result);
// this does NOT work
$key = "['location']['city']";
// $result = $geolocation{$key}; // Notice: Undefined index: ['location']
['city']
// print_r($result);
// this works:
$key = "['location']['city']";
$result = eval('echo $geolocation'."$key;");
print_r($result); // Knoxville


0
David Forger4 months ago
$welcome = getImportedString();
$firstname = "David";
$lastname = "Forger";
echo $welcome;
// before replacement output will be: 
//"Dear $firstname $lastname, welcome to our Homepage"
function replaceVars($match) { 
       return $GLOBALS[$match[1]]; 
}        
$welcome = preg_replace_callback('/\$(\w+)/i', "replaceVars", $welcome);
echo $welcome;
//now output will be:
//"Dear David Forger, welcome to our Homepage"


1
sir_hmba AT yahoo DOT com10 years ago
class foo
{
    var $bar;
    var $baz;
    function foo()
    {
        $this->bar = 3;
        $this->baz = 6;
    }
}
$f = new foo();
echo "f->bar=$f->bar  f->baz=$f->baz\n";
$obj  = 'f';
$attr = 'bar';
$val  = $$obj->{$attr};
echo "obj=$obj  attr=$attr  val=$val\n";


1
antony dot booth at nodomain dot here11 years ago
 foreach ($array as $key => $value) 
 {
  $$key= $value;
 }


1
thien_tmpNOSPAM at hotmail dot com11 years ago
$bases = array('base1', 'base2', 'base3');
$suffixes = array('suffix1', suffix2);
foreach($bases as $base) {
    foreach($suffixes as $suffix) {
        ${$base.$suffix} = "whatever";
        #...etc
    }
}


1
J. Dyer11 years ago
   include("obj.class");
   // this is only a skeletal example, of course.
   $object_array = array();
   // assume the $input array has tokens for parsing.
   foreach ($input_array as $key=>$value){
      // test to ensure the $value is what we need.
         $obj = "obj".$key;
         $$obj = new Obj($value, $other_var);
         Array_Push($object_array, $$obj);
      // etc..
   }


0
ckelley at ca-cycleworks dot com1 year ago
$xmlstr ="<xml><foo><bar><you>Blah</you></bar></foo></xml>";
$xml=SimpleXMLElement($xmlstr);
// no matter what you feed it, it works...
$lvl1="\$xml->foo";
echo n($lvl1."->bar->you");
// n will return Blah as we would hope.
function n($node){ 
    global $xml;
    return eval("return $node;");  
}


0
Omar Juvera2 years ago
//Let's create a new variable: $new_variable_1
$var_name = "new_variable_1"; //$var_name will store the NAME of the new variable
//Let's assign a value to that [$new_variable_1] variable:
$$var_name  = "value 1"; //Value of $new_variable_1 = "value 1"
echo "VARIABLE: " . $var_name;
echo "<br />";
echo "VALUE: " . $$var_name;


1
bpotier at edreamers dot org12 years ago
echo $recordid


1
dnl at au dot ru13 years ago
class someclass {
  var $a = "variable a";
  var $b = "another variable: b";
  }
$c = new someclass;
$d = "b";
echo $c->{$d};


0
andre at AWizardOfAss dot com2 years ago
for ($i = 1; $i <= 5; $i++) {
  ${a.$i} = "value";
}    
echo "$a1, $a2, $a3, $a4, $a5";
//Output is value, value, value, value, value


1
mccoyj at mail dot utexas dot edu13 years ago
class Schlemiel {
var $aVar = "foo";
}
$schlemiel = new Schlemiel;
$a = "schlemiel";
echo $$a->aVar;


0
Sam Yong - hellclanner at live dot com3 years ago
function varvar($str){
    if(strpos($str,'->') !== false){
      // Accessing object property
        $parts = explode('->',$str);
        global ${$parts[0]};
        return ${$parts[0]}->$parts[1];
    }elseif(strpos($str,'[') !== false && strpos($str,']') !== false){
        $parts = explode('[',$str);
        global ${$parts[0]};
        $parts[1] = substr($parts[1],0,strlen($parts[1])-1);
        return ${$parts[0]}[$parts[1]];
    }else{
        global ${$str};
        return ${$str};
    }
}
$arrayTest = array('value0', 'value1', 'test1'=> 'value2', 'test2'=> 'value3');
$objectTest = (object)$arrayTest;
$test = 'arrayTest[1]';
var_dump(varvar($test)); // string(6) "value1"
var_dump($$test); // NULL
$test2 = 'objectTest->test2';
var_dump(varvar($test2)); // string(6) "value3"
var_dump($$test2); // NULL


0
al at o3strategies dot com4 years ago
class testTableData() {
    function testTableData(){  
        // testTable includes the columns: name, user, date
        $query = "SELECT * FROM testTable";      
        $result = mysql_query($query) or die (mysql_error());
        $row = mysql_fetch_array($result);
        foreach ($row as $var => $key) {
            $this->{$var} = $key;
        }    
    }
}
// Access table properties
$table = new testTableData();
echo $table->name;
echo $table->user;
echo $table->date;


0
Matthew (mwwaygoo AT hotmail DOT com)4 years ago
class test_class
{
    var $func='display_UK';  // function name *
    
    function display_UK()
    {
        echo "Hello";
    }
    function display_FR()
    {
        echo "Bonjour";
    }
    function display()
    {
        $this->{$this->func}(); // NOTE the brackets MUST be here and not in the function name above *
    }
}
$test=new test_class();
$test->display_UK(); // to test they work directly
$test->display_FR();
$test->display();


0
moomin4 years ago
function VariableArray($arr, $string)
    {
    preg_match_all('/\[([^\]]*)\]/', $string, $arr_matches, PREG_PATTERN_ORDER);
    
    $return = $arr;
    foreach($arr_matches[1] as $dimension)
        {
        $return = $return[$dimension];
        }
        
    return $return;
    }
$test = array('one' => 'two', 'four' => array(8));
$foo = 'test';
$bar = $$foo;
$baz = "[one]";
$var = VariableArray($bar, $baz); //$var now contains 'two'
$baz = "[four][0]";
$var = VariableArray($bar, $baz); //$var now contains int(8)


0
jupp-mueller at t-online dot de11 years ago
class foo {
  function bar() {
    $bar1 = "var1";
    $bar2 = "var2";
    $this->{$bar1}= "this ";
    $this->{$bar2} = "works";
  }
}
$test = new foo;
$test->bar();
echo $test->var1 . $test->var2;


0
Anonymous11 years ago
$one = "two";
$two = "three";
$three = "four";
$four = "five";
echo $$$$one; //prints 'five'.


0
mstearne at entermix dot com12 years ago
define("DB_X_NAME","database1");
define("DB_Y_NAME","database2");
$DB_Z_NAME="database3";
function connectTo($databaseName){
global $DB_Z_NAME;
$fullDatabaseName="DB_".$databaseName."_NAME";
return ${$fullDatabaseName};
}
print "DB_X_NAME is ".connectTo("X")."<br />";
print "DB_Y_NAME is ".connectTo("Y")."<br />";
print "DB_Z_NAME is ".connectTo("Z")."<br />";


-1
php at willshouse dot the-usual-uk-tld4 years ago
define('FORM_METHOD', 'post');
function getFormVariable( $fieldName, $defaultValue )
{
    global $FILTER_METHOD;
    $getpost = $GLOBALS[ '_' . strtoupper(FILTER_METHOD) ];
    if ( ! array_key_exists( $fieldName, $getpost    ) )    { return $defaultValue; }
    if ( empty(    $getpost[ $fieldName ]            ) )    { return $defaultValue; }
    return $getpost[ $fieldName ];
}
echo "<form method=\"".FORM_METHOD."\">\n";


-1
Anonymous5 years ago
        $MaxRows=100;
        $NumbersOfTime=0;
        extract ($_POST,EXTR_PREFIX_ALL,'pos');
        for ($i = 1; $i <= $MaxRows; $i = $i + 1)
        {
                $tmp = "pos_TimeRecorded{$i}";
                if (isset($$tmp))
                {
                        $TimeRecorded[$i]=$$tmp;
                }
                else
                {
                        $NumbersOfTime=$i-1;
                        break;
                }
        }




Смотрите также:
Описание на ru2.php.net
Описание на php.ru