统一变量语法

大多数情况下,我们可能会遇到方法、变量或类名存储在其它变量中的情况。请看下面的例子:

$objects['class']->name;

在上面的代码中,首先解释 $objects['class'],然后解释属性名称。如前面的示例所示,通常从左到右评估变量。

现在,考虑以下场景:

$first = ['name' => 'second'];
$second = 'Howdy';

echo $$first['name'];

在 PHP 5.x 中,这段代码将被执行,输出结果将是 Howdy。不过,这与从左到右的表达式求值并不矛盾。这是因为 $$first 应该先被求值,然后才是索引名称,但在前面的例子中,它被求值为 ${$first['name']}。很明显,变量语法并不一致,可能会造成混乱。为了避免这种不一致,PHP 7 引入了一种新语法,称为统一变量语法。如果不使用这种语法,前面的示例就会引起注意,无法产生预期的结果。要在 PHP 7 中使用该语法,应添加大括号,如下所示:

echo ${$first['name']};

现在,我们再举一个例子,如下:

class Packt
{
    public $title = 'PHP 7';
    public $publisher = 'Packt Publisher';

    public function getTitle() : string
    {
        return $this->title;
    }

    public function getPublisher() : string
    {
        return $this->publisher;
    }
}

$mthods = ['title' => 'getTitle', 'publisher' => 'getPublisher'];
$object = new Packt();
echo 'Book '.$object->$methods['title'](). ' is published by '.$object->$methods['publisher']();

如果前面的代码在 PHP 5.x 中执行,它将正常工作并输出我们想要的结果。但是,如果我们在 PHP 7 中执行这段代码,将会出现致命错误。错误将出现在代码的最后一行,该行已突出显示。 PHP 7 将首先尝试评估 $object->$method。之后,它将尝试评估 ['title']; 等等; 这是不正确的。

要使其在 PHP 7 中工作,应添加大括号,如以下代码所示:

echo 'Book '.$object->{$methods['title']}(). ' is published by '.$object->{$methods['publisher']}();

进行前面提到的更改后,我们将得到我们想要的输出。