ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…

Иногда ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈΠΌΠ΅Π½Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΏΠΎΠ²Ρ‹ΡˆΠ°ΡŽΡ‚ удобство Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΊΠΎΠ΄ΠΎΠΌ. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ΅ имя ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ β€” имя ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ устанавливаСтся ΠΈ измСняСтся динамичСски. Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ Π²ΠΎΡ‚ Ρ‚Π°ΠΊΠΎΠΉ инструкциСй:

<?php
$a
= 'hello';
var_dump($a);

ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠ°ΠΊ имя ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ hello ΠΈΠ· ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° станСт ΠΈΠΌΠ΅Π½Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΊ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, которая Ρ…Ρ€Π°Π½ΠΈΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ρ‡Π΅Ρ€Π΅Π· Π΄Π²ΠΎΠΉΠ½ΠΎΠΉ Π·Π½Π°ΠΊ Π΄ΠΎΠ»Π»Π°Ρ€Π°. Π’ΠΎ Π΅ΡΡ‚ΡŒ:

<?php
$a
= 'hello';
$
$a = 'world';
var_dump($hello);

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΄Π΅Ρ€Π΅Π²ΠΎ символов PHP Ρ…Ρ€Π°Π½ΠΈΡ‚ Π΄Π²Π° опрСдСлСния ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…: пСрСмСнная $a, которая содСрТит Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ "hello", ΠΈ пСрСмСнная $hello, которая содСрТит Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ "world". ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ инструкция:

<?php
$a
= 'hello';
$
$a = 'world';
echo
"{$a} {$$a}";

...Π²Ρ‹Π²Π΅Π΄Π΅Ρ‚ Ρ‚ΠΎ ΠΆΠ΅, Ρ‡Ρ‚ΠΎ ΠΈ инструкция

<?php
$a
= 'hello';
$
$a = 'world';
echo
"{$a} {$hello}";

ОбС инструкции создадут строку: hello world.

Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈ массивами потрСбуСтся Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚ΡŒ Π½Π΅ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎΡΡ‚ΡŒ. Анализатору синтаксиса трСбуСтся Π·Π½Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΈΠΌΠ΅Π» Π² Π²ΠΈΠ΄Ρƒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π² записи $$a[1]: ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ $a[1] ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΈΠ»ΠΈ $$a, Π° Π·Π°Ρ‚Π΅ΠΌ индСкс [1] этой ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ. Бинтаксис, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚ эту Π½Π΅ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎΡΡ‚ΡŒ, выглядит Π²ΠΎΡ‚ Ρ‚Π°ΠΊ: ${$a[1]} для ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ случая ΠΈ ${$a}[1] для Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ.

Доступ ΠΊ свойствам класса Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ Ρ‡Π΅Ρ€Π΅Π· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈΠΌΠ΅Π½Π° свойств. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ΅ имя свойства Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ Π²Π½ΡƒΡ‚Ρ€ΠΈ области видимости, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ свойство класса. НапримСр, для выраТСния $foo->$bar PHP ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ присутствиС Π² локальной области видимости ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ $bar, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π²ΠΎΠ·ΡŒΠΌΡ‘Ρ‚ ΠΊΠ°ΠΊ имя свойства ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° $foo. Π­Ρ‚ΠΎ справСдливо ΠΈ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° Ρ‡Π΅Ρ€Π΅Π· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ $bar ΠΎΠ±Ρ€Π°Ρ‰Π°ΡŽΡ‚ΡΡ ΠΊ элСмСнту массива.

Π€ΠΈΠ³ΡƒΡ€Π½Ρ‹Π΅ скобки Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ‚ΠΎΡ‡Π½ΠΎ ΠΎΡ‚Π΄Π΅Π»ΠΈΡ‚ΡŒ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ свойства. Π‘ΠΊΠΎΠ±ΠΊΠΈ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ доступ ΠΊ значСниям Π²Π½ΡƒΡ‚Ρ€ΠΈ свойства, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ содСрТит массив, ΠΊΠΎΠ³Π΄Π° имя свойства состоит ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… частСй, Π»ΠΈΠ±ΠΎ ΠΊΠΎΠ³Π΄Π° имя свойства содСрТит символы, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ½Π°Ρ‡Π΅ Π½Π΅ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΈΠ· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ json_decode() ΠΈΠ»ΠΈ ΠΈΠ· модуля SimpleXML).

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #1 ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ свойства

<?php

class Foo
{
public
$bar = 'Π― bar.';
public
$arr = array('Π― A.', 'Π― B.', 'Π― C.');
public
$r = 'Π― r.';
}

$foo = new Foo();
$bar = 'bar';
$baz = ['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";

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°:

Π― bar.
Π― bar.
Π― bar.
Π― r.
Π― B.
Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… нСльзя ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ с ΡΡƒΠΏΠ΅Ρ€Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ массивами PHP. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ $this β€” Ρ‚ΠΎΠΆΠ΅ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ пСрСмСнная, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ нСльзя ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ динамичСски.

οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ 11 notes

up
560
userb at exampleb dot org ΒΆ
16 years ago
<?php

  //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 ...//

?>
up
67
Anonymous ΒΆ
21 years ago
It may be worth specifically noting, if variable names follow some kind of "template," they can be referenced like this:

<?php
// 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";
?>

This is apparent from the notes others have left, but is not explicitly stated.
up
13
marcin dot dzdza at gmail dot com ΒΆ
7 years ago
The feature of variable variable names is welcome, but it should be avoided when possible. Modern IDE software fails to interpret such variables correctly, regular find/replace also fails. It's a kind of magic :) This may really make it hard to refactor code. Imagine you want to rename variable $username to $userName and try to find all occurrences of $username in code by checking "$userName". You may easily omit:
$a = 'username';
echo $$a;
up
16
herebepost (ta at ta) [iwonderr] gmail dot com ΒΆ
9 years ago
While not relevant in everyday PHP programming, it seems to be possible to insert whitespace and comments between the dollar signs of a variable variable.  All three comment styles work. This information becomes relevant when writing a parser, tokenizer or something else that operates on PHP syntax.

<?php

    $foo = 'bar';
    $

    /*
        I am complete legal and will compile without notices or error as a variable variable.
    */
        $foo = 'magic';

    echo $bar; // Outputs magic.

?>

Behaviour tested with PHP Version 5.6.19
up
16
jefrey.sobreira [at] gmail [dot] com ΒΆ
11 years ago
If you want to use a variable value in part of the name of a variable variable (not the whole name itself), you can do like the following:

<?php
$price_for_monday = 10;
$price_for_tuesday = 20;
$price_for_wednesday = 30;

$today = 'tuesday';

$price_for_today = ${ 'price_for_' . $today};
echo $price_for_today; // will return 20
?>
up
7
sebastopolys at gmail dot com ΒΆ
3 years ago
In addition, it is possible to use associative array to secure name of variables available to be used within a function (or class / not tested).

This way the variable variable feature is useful to validate variables; define, output and manage only within the function that receives as parameter 
an associative array : 
    array('index'=>'value','index'=>'value');
index = reference to variable to be used within function
value = name of the variable to be used within function
<?php 

$vars = ['id'=>'user_id','email'=>'user_email'];

validateVarsFunction($vars);

function validateVarsFunction($vars){

    //$vars['id']=34; <- does not work
     // define allowed variables
     $user_id=21;
     $user_email='email@mail.com';

     echo $vars['id']; // prints name of variable: user_id
     echo ${$vars['id']}; // prints 21    
     echo 'Email: '.${$vars['email']};  // print email@mail.com

     // we don't have the name of the variables before declaring them inside the function
}
?>
up
14
mason ΒΆ
15 years ago
PHP actually supports invoking a new instance of a class using a variable class name since at least version 5.2

<?php
class Foo {
   public function hello() {
      echo 'Hello world!';
   }
}
$my_foo = 'Foo';
$a = new $my_foo();
$a->hello(); //prints 'Hello world!'
?>

Additionally, you can access static methods and properties using variable class names, but only since PHP 5.3

<?php
class Foo {
   public static function hello() {
      echo 'Hello world!';
   }
}
$my_foo = 'Foo';
$my_foo::hello(); //prints 'Hello world!'
?>
up
7
Sinured ΒΆ
19 years ago
One interesting thing I found out: You can concatenate variables and use spaces. Concatenating constants and function calls are also possible.

<?php
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
?>

This syntax doesn't work for functions:

<?php
$foo = 'info';
{"php$foo"}(); // Parse error

// You'll have to do:
$func = "php$foo";
$func();
?>

Note: Don't leave out the quotes on strings inside the curly braces, PHP won't handle that graciously.
up
4
nils dot rocine at gmail dot com ΒΆ
13 years ago
Variable Class Instantiation with Namespace Gotcha:

Say you have a class you'd like to instantiate via a variable (with a string value of the Class name)

<?php

class Foo 
{ 
    public function __construct() 
    { 
        echo "I'm a real class!" . PHP_EOL;
    }
}

$class = 'Foo';

$instance = new $class;

?>

The above works fine UNLESS you are in a (defined) namespace. Then you must provide the full namespaced identifier of the class as shown below. This is the case EVEN THOUGH the instancing happens in the same namespace. Instancing a class normally (not through a variable) does not require the namespace. This seems to establish the pattern that if you are using an namespace and you have a class name in a string, you must provide the namespace with the class for the PHP engine to correctly resolve (other cases: class_exists(), interface_exists(), etc.) 

<?php

namespace MyNamespace;

class Foo 
{ 
    public function __construct() 
    { 
        echo "I'm a real class!" . PHP_EOL;
    }
}

$class = 'MyNamespace\Foo';

$instance = new $class;

?>
up
0
hg42 at gmx dot net ΒΆ
3 months ago
there is a comment, that this does not work:
<?php
      $foo = 'info';
      {"php$foo"}(); // Parse error
?>

however this works (at least as tested in 8.3.30):
<?php
      $foo = 'info';
      "php$foo"(); // works
?>
up
3
Nathan Hammond ΒΆ
18 years ago
These are the scenarios that you may run into trying to reference superglobals dynamically. Whether or not it works appears to be dependent upon the current scope.

<?php

$_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();

?>