PHP

Funções Já leu

12 min de leitura

Funções
Até agora escrevemos código sequencial — uma instrução após a outra, em um único bloco. Isso funciona para progr

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

Comentários

Mais em PHP

Configurando o Ambiente de Desenvolvimento
Configurando o Ambiente de Desenvolvimento

Antes de escrever qualquer programa, voc&ecirc; precisa de um ambiente onde o...

Estruturas de Repetição
Estruturas de Repetição

Se as estruturas de controle ensinam o programa a tomar decis&otilde;es, as e...

Variáveis, Tipos de Dados e Operadores
Variáveis, Tipos de Dados e Operadores

Todo programa de computador, em sua ess&ecirc;ncia, faz tr&ecirc;s coisas: re...