require executa o arquivo indicado toda vez que a linha roda; require_once faz o PHP lembrar quais arquivos já foram incluídos e pular se aquele já entrou. A diferença só aparece quando o mesmo arquivo é alcançado mais de uma vez — e aí é decisiva: com require, incluir duas vezes um arquivo que declara uma função ou classe dá o erro fatal Cannot redeclare function/class; com require_once, a segunda inclusão é silenciosamente ignorada e tudo funciona. Este artigo mostra por que isso acontece, quando o _once importa de verdade (e quando é desnecessário) e por que projetos modernos quase não escrevem require à mão.
O mecanismo: por que a segunda inclusão quebra
require é literalmente "cole o conteúdo deste arquivo aqui e execute". Não há mágica: o PHP compila e roda o arquivo incluído no ponto da chamada. Se esse arquivo tem function saudacao() {...} ou class Usuario {...}, essas declarações acontecem ali. Rodar o mesmo require de novo manda o PHP declarar a mesma função outra vez — e o PHP não permite dois nomes iguais no mesmo processo. Resultado: erro fatal que derruba o script na hora.
require_once faz exatamente o mesmo trabalho, com um passo a mais: antes de incluir, ele resolve o caminho absoluto do arquivo e consulta uma lista interna de "já incluídos". Se o caminho já está lá, ele não faz nada e segue adiante. Se não está, inclui e registra. Por isso o _once é imune à redeclaração: o segundo pedido vira um "já tenho esse, ignoro".
O detalhe que engana: o problema não é dar require duas vezes na mesma linha de código. É o mesmo arquivo ser alcançado por caminhos diferentes — config.php inclui db.php, e helpers.php também inclui db.php, e a página inclui os dois. Ninguém escreveu a duplicata de propósito; ela emerge da teia de includes.
1. A página monta suas dependências
index.php precisa das funções e da conexão, então inclui dois arquivos de apoio.
require 'helpers.php'; // funções utilitárias
require 'conexao.php'; // abre o banco
2. Mas cada apoio também puxa a config
Sem você perceber, os dois dependem do mesmo config.php e cada um faz seu require.
// dentro de helpers.php E de conexao.php:
require 'config.php'; // define function baseUrl() {...}
3. config.php roda duas vezes → fatal
O primeiro require 'config.php' declara baseUrl(). O segundo tenta declarar de novo.
Fatal error: Cannot redeclare function baseUrl()
(previously declared in config.php:4) in config.php on line 4
4. require_once quebra o ciclo
Troque os includes de arquivos que declaram coisas por require_once. O segundo pedido de config.php vê que ele já entrou e é ignorado — sem erro.
require_once 'config.php'; // 1ª vez: inclui. 2ª vez: pula.
// arquivo que DECLARA algo, incluído por dois caminhos:
require 'config.php';
require 'config.php';
// Fatal error: Cannot redeclare function baseUrl()
// (o script morre aqui — nada depois roda)require_once 'config.php';
require_once 'config.php';
// a 2ª chamada é ignorada; baseUrl() existe uma vez só
echo baseUrl(); // funcionaQuando o _once importa — e quando não
A regra prática: use require_once para arquivos que definem algo que não pode existir em duplicata — funções, classes, constantes, configuração. Para esses, incluir duas vezes é sempre erro (ou desperdício), então o _once é a escolha certa por padrão.
Antecipando a próxima pergunta: então é só usar _once em tudo? Não — e aqui mora um mal-entendido comum. Existe código que você quer rodar mais de uma vez: um template/partial que renderiza uma linha de tabela, um card, um trecho de HTML dentro de um laço. Esse arquivo não declara nada — ele produz saída a cada inclusão. Se você usar require_once nele, ele renderiza só na primeira volta do loop e some nas demais.
Você tem linha.php, que imprime <tr> com os dados de um item, e o inclui dentro de um foreach sobre 5 itens. Qual usar?
Ver resposta
Resposta certa: require 'linha.php'; (ou include)
linha.php não declara função/classe — ele gera saída a cada chamada. Com require_once, só a primeira iteração imprimiria a linha; as outras 4 seriam puladas. Para código que deve rodar toda vez, use require/include. O _once é para arquivos de definição, não para templates repetidos.
Diagnóstico: lendo o erro
O próprio erro te diz onde apertar. Cannot redeclare function baseUrl() (previously declared in config.php:4) in config.php on line 4 significa: o arquivo config.php foi incluído mais de uma vez. Ele aponta onde a função foi declarada da primeira vez — logo, o arquivo culpado é aquele. A correção é trocar os require/include daquele arquivo específico por require_once. Você não precisa converter o projeto inteiro; só os arquivos de definição alcançados por múltiplos caminhos.
include vs require: o "opcional" vs "obrigatório"
Rápido, porque a dúvida vem junto: include e require fazem a mesma coisa; a diferença é o que acontece quando o arquivo não existe ou falha. require emite um erro fatal e para o script — use quando a aplicação não faz sentido sem aquele arquivo (config, classes, bootstrap). include emite só um warning e continua — use para algo genuinamente opcional (um banner, um trecho que pode faltar). Cada um tem seu par _once com a mesma lógica de deduplicação: include_once. Na dúvida entre include e require, prefira require: falhar cedo e alto é melhor que seguir com metade das dependências.
O caminho moderno: pare de escrever require para classes
Resumo de decisão
| Situação | Use | Porque |
|---|---|---|
| Arquivo com função/classe/constante/config | require_once |
Incluir 2× redeclara → fatal |
| Template/partial que roda a cada chamada | require (ou include) |
Precisa executar toda vez |
| Dependência obrigatória (bootstrap, config) | require / require_once |
Faltando = fatal, falha cedo |
| Arquivo genuinamente opcional | include / include_once |
Faltando = só warning, segue |
| Classes de um projeto com Composer | autoload PSR-4 | Carrega sob demanda, uma vez, sem require manual |
Em uma frase: require_once para o que se declara uma vez, require/include para o que se executa toda vez — e, para classes, deixe o autoload do Composer fazer isso por você.
A referência de require_once detalha a regra de "incluir uma única vez" e como o PHP identifica o arquivo já carregado — a base do que evita a redeclaração.
require é a inclusão "obrigatória": entenda o comportamento fatal quando o arquivo falha e por que ele é o padrão para dependências essenciais.
include é a variante "opcional" (warning em vez de fatal). Ver os dois lado a lado fecha o entendimento de quando escolher cada um.