按名称动态访问变量(变量变量)

可以通过动态变量名访问变量。变量的名称可以存储在另一个变量中,允许动态访问它。这些变量称为变量变量。

要将变量转换为变量变量,可以在变量前放置一个额外的 $

$variableName = 'foo';
$foo = 'bar';

// The following are all equivalent, and all output "bar":
echo $foo;
echo ${$variableName};
echo $$variableName;

//similarly,
$variableName  = 'foo';
$$variableName = 'bar';

// The following statements will also output 'bar'
echo $foo; 
echo $$variableName; 
echo ${$variableName};

变量变量对于映射函数/方法调用很有用:

function add($a, $b) {
    return $a + $b;
}

$funcName = 'add';

echo $funcName(1, 2); // outputs 3

这在 PHP 类中特别有用:

class myClass {
    public function __construct() {
        $functionName = 'doSomething';
        $this->$functionName('Hello World');
    }

    private function doSomething($string) {
        echo $string; // Outputs "Hello World"
    }
}

有可能,但不要求将 $variableName 放在 {} 之间:

${$variableName} = $value;

以下示例都是等效的并输出 baz

$fooBar = 'baz';
$varPrefix = 'foo';

echo $fooBar;               // Outputs "baz"
echo ${$varPrefix . 'Bar'}; // Also outputs "baz"

仅当变量的名称本身是表达式时才使用 {},如下所示:

${$variableNamePart1 . $variableNamePart2} = $value;

尽管如此,建议始终使用 {},因为它更具可读性。

虽然不建议这样做,但可以链接此行为:

$$$$$$$$DoNotTryThisAtHomeKids = $value;

值得注意的是,许多开发人员认为过度使用变量变量是一种不好的做法。由于它们不适合现代 IDE 的静态分析,因此具有许多变量(或动态方法调用)的大型代码库很快就难以维护。

PHP5 和 PHP7 之间的差异

始终使用 {}() 的另一个原因是 PHP5 和 PHP7 处理动态变量的方式略有不同,这在某些情况下会导致不同的结果。

在 PHP7 中,动态变量,属性和方法现在将严格按照从左到右的顺序进行评估,而不是 PHP5 中特殊情况的混合。以下示例显示评估顺序如何变化。

案例 1:$$foo['bar']['baz']

  • PHP5 解读:${$foo['bar']['baz']}
  • PHP7 解读:($$foo)['bar']['baz']

案例 2:$foo->$bar['baz']

  • PHP5 解读:$foo->{$bar['baz']}
  • PHP7 解读:($foo->$bar)['baz']

案例 3:$foo->$bar['baz']()

  • PHP5 解读:$foo->{$bar['baz']}()
  • PHP7 解读:($foo->$bar)['baz']()

案例 4:Foo::$bar['baz']()

  • PHP5 解读:Foo::{$bar['baz']}()
  • PHP7 解读:(Foo::$bar)['baz']()