Aikido

Por que você deve evitar nomes de variáveis dinâmicos em PHP

Legibilidade

Regra
Evitar dinâmico variáveis dinâmicas
Variável variáveis nomes (variáveis variáveis) podem levar
a dificuldades difícil manutenção o e comportamento . 
A sua utilização é normalmente o resultado de um erro de digitação.

Idiomas suportados: PHP

Introdução

O recurso de variáveis variáveis do PHP permite usar o valor de uma variável como o nome de outra variável com o $$ sintaxe. O que parece um atalho inteligente se torna um pesadelo de depuração quando você não consegue determinar estaticamente quais variáveis existem ou o que elas contêm. Código que usa $$userName em vez de uma propriedade de array ou objeto, impossibilita que as IDEs forneçam autocomplete, que os analisadores estáticos detectem bugs, ou que os desenvolvedores rastreiem o fluxo de dados através da aplicação.

Por que isso importa

Manutenibilidade do código: Variáveis variáveis quebram todas as ferramentas nas quais os desenvolvedores confiam. IDEs não conseguem autocompletar nomes de variáveis, encontrar usos ou refatorar com segurança. Ferramentas de análise estática não conseguem detectar variáveis indefinidas ou incompatibilidades de tipo. A depuração requer inspeção em tempo de execução porque não é possível pesquisar (grep) a base de código para encontrar onde as variáveis são definidas ou lidas.

Implicações de segurança: Quando nomes de variáveis variáveis vêm da entrada do usuário, atacantes podem sobrescrever variáveis arbitrárias, incluindo as críticas para a segurança. Um parâmetro de requisição malicioso poderia ter como alvo $$_GET['var'] para sobrescrever $isAdmin, $userId, ou variáveis de sessão. Isso cria vulnerabilidades de injeção de variáveis que são difíceis de detectar e fáceis de explorar.

Impacto no desempenho: Variáveis variáveis forçam o PHP a realizar lookups em tempo de execução em vez de resolução de símbolos em tempo de compilação. O interpretador deve avaliar o nome da variável dinamicamente a cada acesso, impedindo otimizações que funcionam com variáveis normais. Arrays e objetos fornecem funcionalidade similar com melhores características de desempenho.

Exemplos de código

❌ Não-conforme:

function processFormData($formType) {
    $userForm = ['name' => '', 'email' => ''];
    $adminForm = ['name' => '', 'email' => '', 'role' => ''];

    $formName = $formType . 'Form';
    $$formName = array_merge($$formName, $_POST);

    if ($$formName['email']) {
        sendEmail($$formName['email']);
    }

    return $$formName;
}

// What variable does this actually use?
processFormData('user');

Por que está errado: O código cria $userForm ou $adminForm usando dinamicamente $$formName, tornando impossível rastrear qual variável está sendo modificada. Se $formType vem da entrada do usuário, invasores poderiam injetar nomes de variáveis arbitrários para sobrescrever variáveis críticas.

✅ Compatível:

function processFormData(string $formType): array {
    $forms = [
        'user' => ['name' => '', 'email' => ''],
        'admin' => ['name' => '', 'email' => '', 'role' => '']
    ];

    if (!isset($forms[$formType])) {
        throw new InvalidArgumentException('Invalid form type');
    }

    $form = array_merge($forms[$formType], $_POST);

    if (!empty($form['email'])) {
        sendEmail($form['email']);
    }

    return $form;
}

// Clear which data structure is being used
processFormData('user');

Por que isso importa: O código usa um array explícito com chaves conhecidas, tornando o fluxo de dados óbvio e habilitando todos os recursos da IDE. A validação de entrada previne ataques de injeção, e a análise estática pode verificar se o código está correto.

Conclusão

Substitua variáveis variáveis por arrays, objetos ou uma estrutura de código melhor. Use arrays quando precisar de acesso dinâmico por chave, use objetos para dados estruturados com propriedades conhecidas e refatore a lógica duplicada em abstrações adequadas. Variáveis variáveis quase sempre indicam um problema de design que estruturas de dados apropriadas resolveriam com mais clareza.

FAQs

Dúvidas?

Existem usos legítimos para variáveis variáveis?

Extremamente raro. Motores de template e frameworks de metaprogramação às vezes os utilizam, mas mesmo nesses casos, arrays ou estruturas de dados dedicadas são mais adequadas. Se você acha que precisa de variáveis variáveis, provavelmente precisa de um array com chaves dinâmicas ou de um redesenho do seu fluxo de dados.

E quanto a extract() que cria variáveis dinamicamente?

Evite `extract()` pelas mesmas razões que as variáveis dinâmicas. Ele cria variáveis a partir de chaves de array dinamicamente, quebrando a análise estática e criando riscos de segurança. Use o acesso direto ao array: `$data['key']` em vez de `extract($data); $key`. O código PHP moderno deve tratar `extract()` como um code smell.

Como refatorar código existente que utiliza variáveis variáveis?

Identifique o padrão sendo implementado. Geralmente, é dados de configuração (use arrays), propriedades dinâmicas (use objetos ou arrays) ou lógica condicional (use estruturas de controle apropriadas). Substitua $$varName por $config[$varName] na maioria dos casos. Use objetos quando precisar de segurança de tipo e suporte da IDE para acesso a propriedades.

E quanto ao uso de variáveis variáveis para constantes?

Ainda problemático. Use constant($name) se precisar acessar constantes dinamicamente, embora isso também sugira um problema de design. Melhor abordagem: organize constantes relacionadas em uma classe e use um array ou uma expressão match para selecionar o valor apropriado com base nas condições de tempo de execução.

Variáveis variáveis podem causar colisões de namespace?

Sim, especialmente com superglobais e variáveis de framework. O código usando $$type = 'value' poderia acidentalmente criar $_GET, $_POST ou variáveis de framework como $this em contextos inesperados. Arrays naturalmente criam namespaces para seus dados, prevenindo essas colisões por design.

Fique seguro agora

Proteja seu código, Cloud e runtime em um único sistema centralizado.
Encontre e corrija vulnerabilidades rapidamente de forma automática.

Não é necessário cartão de crédito | Resultados da varredura em 32 segundos.