Até agora escrevemos código sequencial — uma instrução após a outra, em um único bloco. Isso funciona para programas simples, mas rapidamente se torna um problema: código duplicado em vários lugares, dificuldade de manutenção, impossibilidade de testar partes isoladas.
Funções resolvem isso. Uma função é um bloco de código nomeado que pode ser chamado quantas vezes precisar, de qualquer lugar do programa. É o primeiro e mais fundamental mecanismo de reutilização de código em qualquer linguagem.
Neste artigo vamos cobrir tudo sobre funções no PHP moderno: definição, parâmetros, valores padrão, tipagem, retorno, escopo de variáveis, funções anônimas e arrow functions.
Definindo e chamando funções
A palavra-chave function define uma função. O nome segue as mesmas regras das variáveis, mas sem o $, e a convenção é camelCase:
<?php
// Definindo uma função
// A definição NÃO executa o código — apenas o registra
function saudacao(): void
{
echo "Olá, mundo!\n";
}
// Chamando a função — agora o código executa
saudacao(); // Olá, mundo!
saudacao(); // Olá, mundo! — pode chamar quantas vezes quiser
// Funções podem ser definidas depois de onde são chamadas
// O PHP carrega todas as definições antes de executar
dizOi();
function dizOi(): void
{
echo "Oi!\n";
}
Parâmetros e argumentos
Parâmetros são as variáveis declaradas na definição da função. Argumentos são os valores passados na chamada. A distinção é sutil mas importante para a comunicação técnica:
<?php
// $nome e $saudacao são PARÂMETROS — variáveis locais da função
function cumprimentar(string $nome, string $saudacao): void
{
// $nome e $saudacao só existem dentro desta função
echo "$saudacao, $nome!\n";
}
// "Ana" e "Bom dia" são ARGUMENTOS — valores passados na chamada
cumprimentar("Ana", "Bom dia"); // Bom dia, Ana!
cumprimentar("Carlos", "Boa tarde"); // Boa tarde, Carlos!
Valores padrão
Parâmetros podem ter valores padrão, tornando-os opcionais na chamada. Parâmetros com padrão sempre vêm depois dos obrigatórios:
<?php
// $saudacao tem um valor padrão — é opcional na chamada
function cumprimentar(string $nome, string $saudacao = "Olá"): void
{
echo "$saudacao, $nome!\n";
}
cumprimentar("Ana"); // Olá, Ana! — usa o padrão
cumprimentar("Carlos", "Oi"); // Oi, Carlos! — substitui o padrão
// Valores padrão podem ser strings, números, arrays, null — mas não expressões dinâmicas
function criarPerfil(
string $nome,
int $idade = 0,
array $hobbies = [], // array vazio como padrão
?string $bio = null // null como padrão — ? indica que aceita null
): void {
echo "$nome, $idade anos\n";
echo "Hobbies: " . implode(", ", $hobbies) . "\n";
echo "Bio: " . ($bio ?? "Sem bio") . "\n";
}
criarPerfil("Ana", 28, ["leitura", "código"]);
criarPerfil("Bruno"); // usa todos os padrões
Passagem por referência
Assim como no foreach, você pode passar argumentos por referência usando &. A função então modifica a variável original, não uma cópia:
<?php
// Sem referência — a função recebe uma cópia
function dobrarCopia(int $valor): void
{
$valor *= 2; // modifica apenas a cópia local
}
// Com referência — a função modifica a variável original
function dobrarOriginal(int &$valor): void
{
$valor *= 2; // modifica a variável original
}
$numero = 10;
dobrarCopia($numero);
echo $numero; // 10 — não mudou
dobrarOriginal($numero);
echo $numero; // 20 — mudou
Use passagem por referência com moderação. Na maioria dos casos, é melhor retornar o valor modificado do que modificar o original — o código fica mais previsível e testável.
Retorno de valores
A instrução return encerra a execução da função e devolve um valor ao chamador. Uma função que não tem return devolve null implicitamente:
<?php
// Retornando um valor simples
function somar(int $a, int $b): int
{
return $a + $b; // encerra a função e retorna o resultado
}
$resultado = somar(3, 4);
echo $resultado; // 7
// Retorno antecipado — útil para casos de guarda (early return)
// Em vez de aninhar if/else, retorne cedo e mantenha o código "reto"
function calcularDesconto(float $preco, float $percentual): float
{
// Guarda: valida as entradas antes de continuar
if ($preco <= 0) {
return 0.0;
}
if ($percentual <= 0 || $percentual > 100) {
return $preco; // sem desconto se percentual inválido
}
return $preco - ($preco * $percentual / 100);
}
echo calcularDesconto(100.0, 20.0); // 80
echo calcularDesconto(-50.0, 20.0); // 0 — guarda ativada
echo calcularDesconto(100.0, 150.0); // 100 — guarda ativada
// Retornando arrays — muito comum no PHP
function obterDimensoes(float $largura, float $altura): array
{
return [
"largura" => $largura,
"altura" => $altura,
"area" => $largura * $altura,
];
}
$dims = obterDimensoes(5.0, 3.0);
echo $dims["area"]; // 15
Tipagem de funções
O PHP moderno permite declarar os tipos dos parâmetros e do retorno. Isso torna o código mais seguro, mais legível e permite que ferramentas como IDEs e analisadores estáticos detectem erros antes de executar:
<?php
// Tipos escalares nos parâmetros e no retorno
function dividir(float $dividendo, float $divisor): float
{
if ($divisor === 0.0) {
throw new InvalidArgumentException("Divisão por zero não é permitida.");
}
return $dividendo / $divisor;
}
// Union types — PHP 8: aceita mais de um tipo
function formatar(int|float $numero): string
{
return number_format($numero, 2, ',', '.');
}
echo formatar(1234.5); // 1.234,50
echo formatar(1000); // 1.000,00
// Nullable types — o ? indica que o valor pode ser null
function encontrarUsuario(int $id): ?array
{
$usuarios = [
1 => ["nome" => "Ana", "email" => "ana@email.com"],
2 => ["nome" => "Carlos", "email" => "carlos@email.com"],
];
// Retorna null se o usuário não existir — em vez de false ou array vazio
return $usuarios[$id] ?? null;
}
$usuario = encontrarUsuario(1);
$ausente = encontrarUsuario(99);
var_dump($usuario); // array com dados
var_dump($ausente); // NULL
// void — função não retorna nada
function registrarLog(string $mensagem): void
{
echo "[LOG] $mensagem\n";
// return; // opcional — void proíbe retornar um valor
}
// never — PHP 8.1: função que NUNCA retorna (sempre lança exceção ou encerra)
function falharComErro(string $mensagem): never
{
throw new RuntimeException($mensagem);
// Ou: exit(1);
}
Modo estrito
Por padrão, o PHP faz coerção de tipos nos parâmetros. Com declare(strict_types=1), a tipagem se torna rígida e não faz coerção — é a prática recomendada em projetos modernos:
<?php
declare(strict_types=1); // deve ser a primeira linha do arquivo
function somar(int $a, int $b): int
{
return $a + $b;
}
somar(3, 4); // OK
somar(3.5, 4); // TypeError em strict mode — float não é int
somar("3", 4); // TypeError em strict mode — string não é int
Escopo de variáveis
No PHP, variáveis definidas fora de uma função não estão disponíveis dentro dela por padrão. Isso é diferente de muitas outras linguagens e pega muitos iniciantes de surpresa:
<?php
$mensagem = "Olá do escopo global";
function exibir(): void
{
// $mensagem não existe aqui — PHP não herda escopo automaticamente
echo $mensagem; // Notice: Undefined variable $mensagem
}
exibir();
// Para usar uma variável global dentro de uma função, declare com global
// (mas evite isso — é uma prática ruim que cria acoplamento oculto)
function exibirGlobal(): void
{
global $mensagem; // agora $mensagem está acessível
echo $mensagem; // Olá do escopo global
}
// A forma correta: passe o valor como parâmetro
function exibirCorreto(string $mensagem): void
{
echo $mensagem;
}
exibirCorreto($mensagem); // limpo, explícito, testável
Variáveis estáticas
Uma variável estática dentro de uma função mantém seu valor entre chamadas — sem precisar de uma variável global:
<?php
function contarChamadas(): int
{
// static faz a variável persistir entre chamadas da função
// É inicializada apenas uma vez
static $contador = 0;
$contador++;
return $contador;
}
echo contarChamadas(); // 1
echo contarChamadas(); // 2
echo contarChamadas(); // 3
Funções anônimas (closures)
Funções anônimas não têm nome e podem ser atribuídas a variáveis, passadas como argumentos ou retornadas por outras funções. São fundamentais para programação funcional em PHP:
<?php
// Função anônima atribuída a uma variável
$dobrar = function(int $n): int {
return $n * 2;
};
echo $dobrar(5); // 10
// Passando função anônima como argumento
// array_map aplica a função a cada elemento do array
$numeros = [1, 2, 3, 4, 5];
$dobrados = array_map(function(int $n): int {
return $n * 2;
}, $numeros);
print_r($dobrados); // [2, 4, 6, 8, 10]
// use — captura variáveis do escopo externo dentro da closure
$fator = 3;
$multiplicar = function(int $n) use ($fator): int {
// $fator foi capturado do escopo externo via use
return $n * $fator;
};
echo $multiplicar(5); // 15
// use por referência — captura e permite modificar a variável externa
$total = 0;
$acumular = function(int $n) use (&$total): void {
$total += $n; // modifica o $total externo
};
$acumular(10);
$acumular(20);
echo $total; // 30
Arrow functions
Introduzidas no PHP 7.4, as arrow functions são uma sintaxe compacta para funções anônimas de uma única expressão. Elas capturam variáveis do escopo externo automaticamente — sem precisar de use:
<?php
// Função anônima tradicional
$dobrar = function(int $n): int {
return $n * 2;
};
// Arrow function equivalente — muito mais concisa
$dobrar = fn(int $n): int => $n * 2;
echo $dobrar(5); // 10
// Arrow function captura o escopo externo automaticamente
$fator = 3;
$multiplicar = fn(int $n): int => $n * $fator; // $fator capturado automaticamente
echo $multiplicar(5); // 15
// Uso prático com array_map e array_filter
$numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Filtra apenas os pares
$pares = array_filter($numeros, fn(int $n): bool => $n % 2 === 0);
// Dobra cada valor
$dobrados = array_map(fn(int $n): int => $n * 2, $numeros);
// Encadeando — filtra pares e dobra
$paresDobrados = array_map(
fn(int $n): int => $n * 2,
array_filter($numeros, fn(int $n): bool => $n % 2 === 0)
);
print_r($paresDobrados); // [4, 8, 12, 16, 20]
Boas práticas em funções
Uma função deve fazer uma coisa só. Se você precisar de "e" para descrever o que a função faz, ela provavelmente deveria ser dividida em duas.
Nomeie funções com verbos. calcularTotal(), buscarUsuario(), validarEmail() — o nome deve descrever a ação, não o dado.
Prefira early return ao invés de if/else aninhados. O código fica mais linear e fácil de ler.
Limite os parâmetros. Funções com mais de três ou quatro parâmetros geralmente indicam que a função faz coisas demais ou que os parâmetros deveriam ser agrupados em um array ou objeto.
Use declare(strict_types=1) em todos os seus arquivos PHP. Isso transforma erros de tipo em exceções explícitas, em vez de conversões silenciosas que geram bugs difíceis de encontrar.
<?php
declare(strict_types=1);
// ✗ Função que faz coisas demais
function processarPedido(array $itens, string $email, string $endereco, float $frete): void
{
// calcula total, envia email, salva no banco, gera nota fiscal...
}
// ✓ Responsabilidades separadas
function calcularTotalPedido(array $itens, float $frete): float
{
$subtotal = array_sum(array_column($itens, "preco"));
return $subtotal + $frete;
}
function enviarConfirmacao(string $email, float $total): void
{
// envia e-mail de confirmação
}
Resumo
| Conceito | O que aprendemos |
|---|---|
function |
Define um bloco reutilizável com nome |
| Parâmetros | Variáveis locais da função; argumentos são os valores passados |
| Valores padrão | Tornam parâmetros opcionais; sempre após os obrigatórios |
Passagem por & |
Modifica a variável original — use com moderação |
return |
Encerra a função e devolve um valor |
| Early return | Retorne cedo para evitar aninhamento — guarda de validação |
| Tipagem | Declare tipos em parâmetros e retorno; use strict_types=1 |
| Escopo | Variáveis externas não entram na função — passe como parâmetro |
static |
Variável que persiste entre chamadas da mesma função |
| Closure | Função anônima; usa use para capturar escopo externo |
| Arrow function | fn() => — compacta, captura escopo automaticamente |
Referências e leituras para aprofundar
-
Funções — Manual oficial do PHP https://www.php.net/manual/pt_BR/language.functions.php Documentação completa sobre funções, incluindo funções variádicas, named arguments e todos os detalhes de comportamento.
-
Funções anônimas (Closures) — Manual oficial do PHP https://www.php.net/manual/pt_BR/functions.anonymous.php Documentação específica sobre closures e o uso de
usepara captura de escopo. -
Arrow functions — Manual oficial do PHP https://www.php.net/manual/pt_BR/functions.arrow.php Documentação das arrow functions introduzidas no PHP 7.4, com exemplos e comparação com closures.
-
RFC: Arrow functions 2.0 https://wiki.php.net/rfc/arrow_functions_v2 A proposta formal das arrow functions. Explica a motivação, o design e as limitações (apenas uma expressão, sem corpo de bloco).
-
declare(strict_types) — Manual oficial do PHP https://www.php.net/manual/pt_BR/language.types.declarations.php#language.types.declarations.strict Como e por que usar o modo estrito de tipos. Fundamental para projetos PHP modernos.
-
MARTIN, Robert C. Clean Code. Prentice Hall, 2008. Capítulo 3: Functions. https://www.oreilly.com/library/view/clean-code-a/9780136083238/ O capítulo mais importante do livro. Trata de tamanho de funções, nomes, parâmetros e o princípio da responsabilidade única aplicado a funções.