URL completo em PHP: como obter rapidamente e sem erros

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Como obter o URL completo em PHP sem enlouquecer?

\n\n

Todo desenvolvedor PHP já enfrentou a tarefa: "Como obtenho o URL completo da página atual?". Parece simples — pegue $_SERVER['HTTP_HOST'], adicione $_SERVER['REQUEST_URI'] — e pronto. Mas a realidade, como sempre, traz suas complicações. HTTP ou HTTPS? E se a porta não for padrão? E se o site estiver atrás de um proxy? E se não for apenas obter, mas fazer isso rapidamente, sem vazamentos de memória e com margem para o futuro?

\n\n

A pergunta "Get the full URL in PHP" no Stack Overflow acumulou milhares de visualizações e dezenas de respostas. Não é por acaso: o tema parece simples, mas as armadilhas são muitas. Hoje vamos abordar não apenas "como fazer", mas como fazer corretamente, rápido e de forma confiável. Vamos lá!

\n\n

Por que copiar diretamente de $_SERVER é ruim?

\n\n

Desenvolvedores iniciantes frequentemente escrevem assim:

\n\n
$url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
\n\n

À primeira vista, funciona. Mas vejamos os problemas:

\n
    \n
  • Sem HTTPS. Se o site usa HTTPS, você obterá http:// — e o navegador reclamará de conteúdo misto.
  • \n
  • Porta. Se a porta não for padrão (ex.: 8080), ela será perdida se não usar $_SERVER['SERVER_PORT'].
  • \n
  • Proxy e balanceadores. Atrás de um proxy reverso (Nginx, Cloudflare), $_SERVER['HTTP_HOST'] pode não ser o que o usuário vê.
  • \n
  • Segurança. O valor de HTTP_HOST pode ser manipulado por um invasor (injeção de cabeçalho Host).
  • \n
\n\n

Resumindo, copiar e colar da primeira resposta no Stack Overflow não é a melhor opção. Vamos escrever uma função correta e eficiente.

\n\n

Função de referência: obtendo o URL completo corretamente

\n\n

Aqui está uma função confiável que considera todos os cenários principais:

\n\n
function getFullUrl(): string {\n    $protocol = 'http';\n    if (\n        (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')\n        || (int)$_SERVER['SERVER_PORT'] === 443\n    ) {\n        $protocol = 'https';\n    }\n\n    // Considera cabeçalhos de proxy (se confiável)\n    $host = $_SERVER['HTTP_HOST'] ?? '';\n    if (empty($host) && !empty($_SERVER['SERVER_NAME'])) {\n        $host = $_SERVER['SERVER_NAME'];\n    }\n\n    // Verificação de porta\n    $port = (int)$_SERVER['SERVER_PORT'];\n    $portSuffix = '';\n    if (\n        ($protocol === 'http' && $port !== 80)\n        || ($protocol === 'https' && $port !== 443)\n    ) {\n        $portSuffix = ':' . $port;\n    }\n\n    $uri = $_SERVER['REQUEST_URI'] ?? '/';\n\n    return $protocol . '://' . $host . $portSuffix . $uri;\n}
\n\n

O que é importante aqui?

\n
    \n
  • Verificamos HTTPS — método padrão, funciona em 99% dos casos.
  • \n
  • Consideramos SERVER_PORT — se o site estiver em porta não padrão, não a perdemos.
  • \n
  • Opção alternativa via SERVER_NAME — caso HTTP_HOST esteja vazio.
  • \n
  • Não usamos $_SERVER['SCRIPT_URI'] — não está disponível em todos os lugares.
  • \n
\n\n

Otimização de desempenho: quando cada milissegundo conta

\n\n

Se você chama essa função em cada página ou em um loop, vale a pena pensar na velocidade. Aqui estão algumas dicas:

\n\n

1. Cache do resultado

\n

Se o URL não muda dentro de uma mesma requisição (e não muda), faça cache:

\n\n
function getFullUrlCached(): string {\n    static $url = null;\n    if ($url === null) {\n        $url = getFullUrl(); // usa nossa função acima\n    }\n    return $url;\n}
\n\n

Uma variável estática mantém o valor após a primeira chamada — sem recálculos desnecessários.

\n\n

2. Evite operações desnecessárias

\n

Não use filt

Blogs

Book Recommendations