# PHP para Iniciantes: Variáveis - Variáveis variáveis

Talvez o título mais confuso da história, mas logo tudo fará sentido, tenha paciência. A questão sobre variáveis variáveis é que você precisa se perguntar: **o que é uma variável?**

E a resposta é simples: qualquer coisa que varia. **#stonks**

Então se você tem duas coisas que variam e uma coisa que varia entre essas duas coisas que variam, você tem uma **variável que varia**, uma variável variável.

> QUE

É punk, eu sei... Esse é tipo de assunto que fica mais claro com exemplos, então vamos começar de trás pra frente.

## Propriedades variáveis

> Como ***cientista de dados***,<br/>
> quero ***armazenar uma informação capaz de referenciar o algoritmo que deve ser acionado por cada indivíduo***,<br/>
> para ***poder acionar o respectivo algoritmo no código quando for invocado***.

Com essa história de usuário, eu quero:

- construir ao menos **2 algoritmos** distintos (leia-se dois métodos, não importa o que façam, rs);
- construir uma classe **capaz de receber um desses algoritmos ao instanciar um objeto**;
- acionar o algoritmo de cada instância para executar.

No PHP, tem uma forma de se fazer isso sem muito esforço, passando uma referência da função diretamente pro atributo da classe, virando um `callable`. Mas e se eu precisar armazenar isso no banco de dados? Então não dá pra simplesmente passar um callalbe. Você precisa ter isso como um dado representando o nome do método que precisa ser acionado...

Parece complexo? Então vamos ao código:

```php
<?php // PHP 8!

class Exemplo {
    public function __construct(
        private string $metodo
    ) { }

    private function algoritmo1(int|float $numero): int|float
    {
        return $numero * 2;
    }

    private function algoritmo2(int|float $numero): int|float
    {
        return $numero * 5;
    }

    public function rodar(int|float $numero): int|float
    {
        return $this->{$this->metodo}($numero);
    }
}

$x2 = new Exemplo('algoritmo1');
$x5 = new Exemplo('algoritmo2');

var_dump($x2->rodar(3)); // int(6)
var_dump($x2->rodar(4)); // int(8)
var_dump($x2->rodar(5)); // int(10)
var_dump($x2->rodar(3.3)); // float(6.6)

var_dump($x5->rodar(3)); // int(15)
var_dump($x5->rodar(4)); // int(20)
var_dump($x5->rodar(5)); // int(25)
var_dump($x5->rodar(3.3)); // float(16.5)
```

> Mas Kiko, como isso é uma variável variável?

A mágica está no método `Exemplo->rodar`. Note que o código não está nada bom, afinal, se você colocar um dado no atributo `metodo` que não seja o nome válido, dará erro. Mas considerando a proposta, a variável variável acontece na hora de acionar esse método, no trecho `$this->{$this->metodo}($numero)`. Isso está explicitamente dizendo:

1. `$this->...($numero)`, o que é `...`?
2. `... = $this->metodo`, que é `'algoritmo1'` no `$x2` e `'algoritmo2'` no `$x3`;
3. portanto, para cada objeto, `...` terá um valor diferente, resultando:
    - `$this->algoritmo1($numero)` no `$x2`;
    - `$this->algoritmo2($numero)` no `$x3`.

> Mas Kiko, ainda não entendi, o que isso tem a ver com variável variável?

Acontece que eu inverti o assunto propositalmente para termos um exemplo palpável... Para chegarmos às variáveis variáveis, podemos reescrever tudo isso aí em forma de funções e as coisas ficarão ainda mais claras.

## Variáveis variáveis

```php
<?php // PHP 8

function rodar(string $funcao, int|float $numero): int|float
{
    $x2 = fn () => $numero * 2;
    $x5 = fn () => $numero * 5;
    return $$funcao($numero);
}

var_dump(rodar('x2', 3)); // int(6)
var_dump(rodar('x2', 4)); // int(8)
var_dump(rodar('x2', 5)); // int(10)
var_dump(rodar('x2', 3.3)); // float(6.6)

var_dump(rodar('x5', 3)); // int(15)
var_dump(rodar('x5', 4)); // int(20)
var_dump(rodar('x5', 5)); // int(25)
var_dump(rodar('x5', 3.3)); // float(16.5)
```

Ok, eu sei que tem muita coisa pra falar... Do nada um `arrow function`, além de agregar tipos de dados na declaração da função... Pretendo abordar esses assuntos nos artigos sobre funções, beleza? Por agora, foca no `$$funcao`.

Quando você usa mais de um cifrão em uma variável, você está invocando **n** variáveis sequencialmente. E isso é uma operação recursiva: de dentro pra fora.

Em nosso exemplo, você está acessando, primeiramente, a variável `$funcao`, que pode ter os valores `'x2'` e `'x5'`. Depois, você acessa a variável cujo nome vem da operação anterior: `${$funcao}`, que vira `${'x2'}` => `$x2` ou `${'x5'}` => `$x5`.

Por fim, acionamos a função: `$x2($numero)` ou `$x5($numero)`.

Ficou mais claro? Bom, o motivo de ter contado tanta historinha é que a maioria dos exemplos que você pode encontrar na internet são bem mais genéricos, e agora vou mostrar a profundidade por trás das **variáveis variáveis**.

```php
<?php

$enem = "prova";
$prova = "dificil";
$dificil = "ilusao";
$ilusao = "ficarRico";
$ficarRico = "trabalhar";
$trabalhar = "seFormar";
$seFormar = "enem";

var_dump($enem); // string(prova)
var_dump($$enem); // string(dificil), $$enem = $prova = 'dificil'
var_dump($$$enem); // string(ilusao), $$$enem = $$prova = $dificil = 'ilusao'
var_dump($$$$enem); // string(ficarRico), $$$$enem = $$$prova = $$dificil = $ilusao = 'ficarRico'
var_dump($$$$$enem); // string(trabalhar), $$$$$enem = $$$$prova = $$$dificil = $$ilusao = $ficarRico = 'trabalhar'
var_dump($$$$$$enem); // string(seFormar), $$$$$$enem = $$$$$prova = $$$$dificil = $$$ilusao = $$ficarRico = $trabalhar = 'seFormar'
var_dump($$$$$$$enem); // string(enem), $$$$$$$enem = $$$$$$prova = $$$$$dificil = $$$$ilusao = $$$ficarRico = $$trabalhar = $seFormar = 'enem'
var_dump($$$$$$$$enem); // string(prova), ou seja, $$$$$$$$enem = (......) = $enem = 'prova'
```

E tome variável variando!

Assim como toda variável, você não pode criar variáveis com palavras reservadas. No caso, até o momento é o `$this`. Você também não pode referenciar variáveis globais. Se for a intenção, basta usar a variável pré-definida `$_GLOBALS` ao invés de tentar invocar chamando `global $$$var`, que não funciona. Use `$_GLOBALS[$$var]` no lugar.

Curtiu? Deu pra entender tudo direitinho? Bom, eu gosto muito dessas coisas que dão nó na nossa mente, por isso que esse assunto é o meu favorito. Escrevi esse artigo 100% da minha cabeça, consultei a documentação somente depois de escrever pra ver se não esqueci algum assunto, mas falei todinho: prova que tá gravado na alma, com carinho. Se você também achou interessante, compartilha com os amigos! E se ficou com alguma dúvida, não hesite em perguntar! Fechado?

**Inté!**
