Médio PHP

Union type e nullable

Enunciado

Crie uma função descrever que recebe um parâmetro int|string|null e retorna uma string. Se o valor for null, retorne "vazio". Se for int, retorne "número: X". Se for string, retorne "texto: Y". Use declare(strict_types=1); e tipos explícitos. Chame a função com 10, "PHP" e null, imprimindo cada resultado em uma linha.

Requisitos

  • A função deve ter parâmetro do tipo int|string|null e retorno string.
  • Deve tratar os três casos: inteiro, string e null.
  • A saída deve ter exatamente três linhas, na ordem: número: 10, texto: PHP, vazio.

Código inicial

<?php

declare(strict_types=1);

// Complete a função
function descrever(int|string|null $valor): string {
    // ...
}

echo descrever(10), PHP_EOL;
echo descrever("PHP"), PHP_EOL;
echo descrever(null), PHP_EOL;

Saída esperada

número: 10
texto: PHP
vazio
Ver dica

Use is_int(), is_string() e is_null() ou === null para diferenciar os tipos. A ordem das verificações importa.

Mostrar solução
<?php

declare(strict_types=1);

function descrever(int|string|null $valor): string {
    if ($valor === null) {
        return "vazio";
    }
    if (is_int($valor)) {
        return "número: $valor";
    }
    // Se não é null nem int, só pode ser string
    return "texto: $valor";
}

echo descrever(10), PHP_EOL;
echo descrever("PHP"), PHP_EOL;
echo descrever(null), PHP_EOL;

Passo a passo

  1. declare(strict_types=1); garante que os tipos sejam verificados sem conversão.
  2. O parâmetro int|string|null é um union type que aceita inteiro, string ou null.
  3. O retorno é declarado como string.
  4. A primeira verificação é $valor === null, que retorna "vazio" imediatamente.
  5. Depois, is_int($valor) identifica inteiros e retorna a string formatada.
  6. Se nenhuma das condições anteriores for verdadeira, o valor só pode ser string, então retornamos "texto: $valor".
  7. As chamadas passam valores de tipos diferentes, e cada uma produz a saída esperada.

Por que funciona

O union type int|string|null permite que a função aceite três tipos distintos. Com strict_types=1, o PHP verifica se o argumento passado é exatamente um desses tipos. A verificação em ordem (null, int, string) garante que cada caso seja tratado corretamente. Se tentássemos passar um float, por exemplo, o PHP lançaria TypeError, pois float não está no union type.

Erros comuns

  • Esquecer de incluir null no union type: int|string não aceita null, e a chamada descrever(null) gera TypeError.
  • Usar == em vez de === para comparar com null: $valor == null também considera 0, "" e false como null, causando resultados errados.
  • Verificar is_string() antes de is_int(): como a ordem não afeta a lógica aqui, mas se usarmos is_numeric() poderíamos classificar strings numéricas como números incorretamente.

Outra forma de resolver

Usar match(true) para uma expressão mais concisa:

return match(true) {
    $valor === null => "vazio",
    is_int($valor)  => "número: $valor",
    default         => "texto: $valor",
};

O match é preferível quando há muitas condições e se deseja evitar vários if.

Saída esperada

número: 10
texto: PHP
vazio