Funções avançado
Nesta aula avançada de funções em PHP, exploramos parâmetros variádicos, argumentos nomeados (PHP 8), operador spread e type juggling em parâmetros, com exemplos práticos e boas práticas.
Nesta aula, vamos aprofundar o uso de funções em PHP, abordando recursos modernos e importantes para escrever código mais flexível e expressivo. Você aprenderá sobre parâmetros variádicos, que permitem receber um número indefinido de argumentos, argumentos nomeados introduzidos no PHP 8, o operador spread para expandir arrays e a tipagem dinâmica (type juggling) aplicada a parâmetros de funções.
Esses conceitos são fundamentais para criar funções reutilizáveis e adaptáveis a diferentes contextos, além de facilitar a leitura e manutenção do código. Vamos explorar cada tópico com exemplos claros e práticos.
Parâmetros variádicos (...)
Os parâmetros variádicos permitem que uma função aceite um número variável de argumentos. Eles são indicados por três pontos (...) antes do nome do parâmetro. Dentro da função, esse parâmetro se torna um array contendo todos os argumentos passados.
Exemplo clássico é a função sum que soma todos os números fornecidos:
function sum(...$numbers) {
return array_sum($numbers);
}
echo sum(1, 2, 3, 4); // 10Você pode misturar parâmetros normais com variádicos, mas o variádico deve ser o último na lista de parâmetros:
function greet($greeting, ...$names) {
foreach ($names as $name) {
echo "$greeting, $name!\n";
}
}
greet("Hello", "Alice", "Bob", "Charlie");Isso torna as funções mais flexíveis, especialmente em situações como logging ou manipulação de listas de argumentos.
Argumentos nomeados (PHP 8)
Argumentos nomeados permitem passar argumentos para uma função especificando o nome do parâmetro, em vez de depender apenas da ordem. Isso melhora a legibilidade e evita erros em funções com muitos parâmetros opcionais.
Sintaxe: nome_do_parametro: valor. Exemplo:
function createUser($name, $email, $age = null, $active = true) {
// ...
}
createUser(name: "João", email: "joao@example.com", active: false);Você pode misturar argumentos posicionais e nomeados, mas os nomeados devem vir após os posicionais. Além disso, a ordem dos nomeados não importa.
Isso é particularmente útil em funções com muitos parâmetros opcionais, como em construtores ou funções de configuração.
Spread
O operador spread (...) é usado para expandir arrays ou objetos iteráveis em listas de argumentos ao chamar funções. É o inverso dos parâmetros variádicos.
Exemplo com array_push:
$numbers = [1, 2, 3];
$more = [4, 5];
array_push($numbers, ...$more); // $numbers agora é [1,2,3,4,5]Spread também pode ser usado em declarações de array para concatenar arrays:
$arr1 = [1, 2];
$arr2 = [3, 4];
$merged = [...$arr1, ...$arr2]; // [1,2,3,4]No contexto de funções, spread permite passar um array como argumentos individuais, especialmente útil com funções variádicas:
function multiply($a, $b) {
return $a * $b;
}
$nums = [2, 3];
echo multiply(...$nums); // 6Spread funciona com qualquer iterável (arrays, objetos Traversable).
Type juggling em parâmetros
PHP é uma linguagem de tipagem dinâmica, o que significa que os tipos das variáveis podem mudar conforme o contexto. Isso também se aplica a parâmetros de funções: você pode passar valores de qualquer tipo, e o PHP tentará convertê-los automaticamente se necessário (type juggling).
Por exemplo, uma função que espera uma string pode receber um inteiro, que será convertido para string:
function show($value) {
echo "Valor: " . $value;
}
show(123); // "Valor: 123"No entanto, isso pode levar a comportamentos inesperados. Para evitar isso, o PHP 7+ introduziu declarações de tipo (type hints) e modo estrito (strict_types).
Com declare(strict_types=1); no início do arquivo, o PHP lança um TypeError se o tipo não corresponder exatamente:
declare(strict_types=1);
function sum(int $a, int $b): int {
return $a + $b;
}
echo sum(2.5, 3); // TypeError: Argument 1 passed to sum() must be of the type int, float givenSem strict types, o PHP fará coerção automática (ex.: 2.5 vira 2). Boa prática é sempre declarar tipos e usar strict types para evitar bugs sutis.
Boas práticas e observações finais
Ao usar parâmetros variádicos, lembre-se de que eles capturam todos os argumentos extras, então evite usá-los em funções que já têm muitos parâmetros opcionais. Prefira argumentos nomeados para maior clareza. O operador spread é excelente para trabalhar com arrays de forma concisa. Quanto ao type juggling, sempre declare tipos nos parâmetros e utilize strict types para garantir previsibilidade.
Exercícios
Crie uma função chamada
concatque aceite um número variável de strings e as concatene com um separador (padrão: espaço). Use parâmetros variádicos.✓ Resposta:function concat(string $separator = " ", ...$strings): string { return implode($separator, $strings); } echo concat("-", "a", "b", "c"); // "a-b-c"Usando argumentos nomeados, chame a função
createUserabaixo passando apenasnameeemail, mas definaactivecomo false:function createUser($name, $email, $age = null, $active = true) { /* ... */ }✓ Resposta:createUser(name: "Maria", email: "maria@example.com", active: false);Dado o array
$numbers = [5, 10, 15];, use o operador spread para chamar a funçãoarray_sumcom esses números.✓ Resposta:$numbers = [5, 10, 15]; echo array_sum(...$numbers); // 30Escreva uma função
divideque receba dois números e retorne a divisão, mas com type hints para float. Teste passando inteiros e veja o comportamento sem strict types.✓ Resposta:function divide(float $a, float $b): float { return $a / $b; } echo divide(10, 3); // 3.3333333333333 (type juggling converte int para float)Crie uma função que aceite um número variádico de inteiros e retorne a média. Use type hints e declare strict types. Teste passando floats.
✓ Resposta:declare(strict_types=1); function average(int ...$numbers): float { return array_sum($numbers) / count($numbers); } // average(2.5, 3); // TypeError: Argument 1 must be of type int, float given