Os dois fazem a mesma coisa: puxam outro arquivo PHP para dentro do script e o executam ali. A diferença aparece quando algo dá errado — e ela cabe numa frase: se o arquivo não puder ser carregado, o include emite um aviso e segue em frente; o require lança um erro fatal e para o script na hora.
O que os dois fazem (e é idêntico)
Tanto include quanto require executam o arquivo incluído no escopo da linha que os chamou — as variáveis definidas lá dentro passam a existir aqui fora, e vice-versa:
// config.php
$dbHost = 'localhost';
// index.php
require 'config.php';
echo $dbHost; // 'localhost' — a variável nasceu no escopo de quem incluiu
Até aqui, trocar um pelo outro não muda nada. A escolha só importa no cenário de falha.
A diferença: o que acontece quando o arquivo falta
include 'nao-existe.php'; // Warning: include(): Failed to open stream...
echo 'esta linha RODA';
require 'nao-existe.php'; // Fatal error: Failed opening required...
echo 'esta linha NUNCA roda';
É isso. include = aviso (o script continua, sem o conteúdo do arquivo). require = erro fatal (o script morre ali). Dessa diferença sai a regra de uso:
// Config essencial com include: se o arquivo faltar, o script
// segue rodando sem $dbHost — e o erro estoura longe daqui
include 'config.php';
$pdo = new PDO("mysql:host=$dbHost", $user, $pass);// Essencial = require: faltou, parou aqui, com o erro
// apontando exatamente a causa
require __DIR__ . '/config.php';
$pdo = new PDO("mysql:host=$dbHost", $user, $pass);E o include_once / require_once?
As versões _once incluem o arquivo só se ele ainda não foi incluído naquela execução. Servem para arquivos que definem coisas — funções, classes, constantes — em que uma segunda inclusão causaria erro de redeclaração:
require_once 'helpers.php'; // define funções
require_once 'helpers.php'; // ignorado — sem "Cannot redeclare function"
Para fragmentos de template que imprimem conteúdo, o _once seria um bug: se você inclui o mesmo cartão três vezes, quer que ele apareça três vezes.
A pegadinha do caminho relativo
Um caminho como 'config.php' não é resolvido a partir do arquivo que contém o include — o PHP procura primeiro pelo include_path (que normalmente começa pelo diretório de onde o processo foi executado). Resultado: o include funciona quando o script roda de um jeito e quebra quando roda de outro (CLI vs. servidor, por exemplo).
// dentro de /app/src/boot.php
require 'config.php'; // depende de onde o PHP foi chamado — frágil
require __DIR__ . '/config.php'; // sempre relativo a ESTE arquivo — à prova de tudo
Bônus: include e require retornam valor
Se o arquivo incluído termina com return, a expressão devolve esse valor — é o padrão clássico para arquivos de configuração (o Laravel usa exatamente isso em config/):
// config.php
return ['host' => 'localhost', 'port' => 3306];
$config = require __DIR__ . '/config.php';
echo $config['host']; // 'localhost' — sem variável global solta
Resumo de decisão
| Situação | Use |
|---|---|
| Configuração, classes, bootstrap (essencial) | require |
| Fragmento opcional de template | include |
| Arquivo que define funções/classes | require_once |
| Arquivo de config que retorna um array | $x = require ... |
Continue de onde este artigo parou
A página oficial detalha a ordem exata de busca dos caminhos e o comportamento do retorno.
Curta e direta — vale ler junto com a do include para fixar o contraste.