Jonathan Lamim (Convidado)
Jonathan Lamim (Convidado)

#3 PHP 7 – Sintaxe uniforme de variáveis

A sintaxe de variáveis do PHP é, de certa forma, inconsistente, particularmente o que diz respeito a variáveis-variáveis e variáveis propriedades.

Por exemplo, veja a sintaxe $objeto->$array[chave]; estamos sempre esperando que primeiro seja resolvido o $array[chave] para depois acessar a propriedade do objeto. Com a sintaxe uniforme de variáveis, toda essa inconsistência foi resolvida.

A partir do PHP 7, todas as variáveis passam a ser avaliadas da esquerda para a direita, sendo um “problema” somente em caso de variáveis dinâmicas complexas e propriedades.

Veja no código a seguir que é possível obter o mesmo comportamento do PHP 5.x no PHP 7, ou vice-versa, especificando de forma explícita a ordem das operações com o uso de parênteses () e chaves {}.

// Sintaxe
$$var['chave']['chave2'];

// PHP 5.x:
// Usando um array multidimensional como nome da variável
${$var['chave']['chave2']};

// PHP 7:
// Acesssando um array multidimensional dentro de uma variável-variável
($$var)['chave']['chave2'];

// Sintaxe
$var->$prop['chave'];

// PHP 5.x:
// Usando um array como nome de propriedade
$var->{$prop['chave']};

// PHP 7:
// Acessando um array dentro de uma variável-propriedade
($var->$prop)['chave'];


// Sintaxe
$var->$prop['chave']();

// PHP 5.x:
// Usando um array como nome de um método
$var->{$prop['chave']}();

// PHP 7:
// Chamando um closure dentro de um array como variável-propriedade
($var->$prop)['key']();

// Sintaxe
ClassName::$var['chave']();

// PHP 5.x:
// Usando um array como nome de método estático
ClassName::{$var['chave']}();

// PHP 7:
// Chamando um closure dentro de um array com variável estática variable
(ClassName::$var)['chave']();

Um dos principais benefícios da sintaxe uniforme de variáveis é que ela permite muitas combinações de sintaxe, e muitas dessas novas combinações estão disponíveis para uso.

// Chama um closure dentro de um array retornando outro closure
$foo()['bar']();

// Chama uma propriedade referenciando um array literal
[$obj1, $obj2][0]->prop;

// Acessa um caracter pelo índice na string retornada
getStr(){0};

Além disso, o PHP 7 suporta – em alguns casos – dois pontos duplos aninhados.

// Acessa uma propriedade estática no nome da classe ou objeto dentro de um array
$foo['bar']::$baz;

// Acessa uma propriedade estática no nome da classe ou objeto dentro de um array retornando para o metódo estático chamado em um nome de classe ou objeto
$foo::bar()::$baz;

// Chama um método estático em uma classe ou objeto retornado por uma chamada de método
$foo->bar()::baz();

Ainda existe uma série de casos ambíguos que não podem ser resolvido, mesmo com a nova sintaxe de variáveis, e mesmo quando a adição de parênteses e chaves.

$foo = 'Foo';
$class = 'CLASS';
$constant = 'BAR';

echo $foo::$class::$constant;
echo $foo::{$class}::$constant;
echo $foo::{"$class"}::$constant;
echo $foo::{"$class"}::{"$constant"};
echo $foo::CLASS::$constant;
echo $foo::CLASS::{"$constant"};
echo $foo::($class)::($constant);

Além disso, agora você pode fazer chamadas de métodos e funções dobrando os parênteses.

// Chama o callback retornado por um método
foo()();

// Chama um callback retornado por um método instanciado
$foo->bar()();

// Chama um callback retornado por um amétodo estático
Foo::bar()();

// Chama um callback retornado por outro callback
$foo()();

Desde o PHP 5.4 era possível desreferenciar arrays retornados por métodos e funções, agora com o PHP 7 é possível fazer isso com qualquer expressão válida colocada entre parênteses.

// Acessando a chave de um array
(expression)['foo'];

// Acessando uma propriedade
(expression)->foo;

// Chamando um método
(expression)->foo();

// Acessando uma propriedade estática
(expression)::$foo;

// Chamando um método estático
(expression)::foo();

// Chamando um callback
(expression)();

// Acessando um caracter
(expression){0};

Isso permite, finalmente, chamar um closure quando ele for definido, e chamar um callback dentro da propriedade de um objeto.

// Define e chama imediatamente um closure sem atribuição
(function() { /* ... */ })();

// Chama um callbacl dentro da propriedade de um objeto
($obj->callable)();

O PHP 7 também dá a possibilidade de chamar métodos usando “array-notation”.

// Chama um método estático dinâmico
["className", "staticMethod"]();

// Chama uma método de instÂncia dinâmico
[$object, "method"]();

// Usa uma string escalar como nome de classe
'className'::staticMethod();

Uma possibilidade futura da sintaxe de variáveis do PHP 7 é a perspectiva de trabalho com objetos escalares, ou seja, a capacidade de chamar métodos que agem diretamente sobre um valor.

// converte os caracteres da string para minúsculo
"string"->toLower();

Nesse artigo você viu um pouco sobre a nova sintaxe de variáveis do PHP 7, e no próximo falarei sobre “Type Hints”, a característica excitante do PHP 7.

Até o próximo artigo!

Jonathan Lamim (Convidado)
Jonathan Lamim (Convidado)