PHP

Guia Completo de Roteamento HTTP em PHP: Criando um Router Simples

7 min de leitura

Guia Completo de Roteamento HTTP em PHP: Criando um Router Simples

O que é Roteamento HTTP e Por Que Importa Roteamento HTTP é o mecanismo fundamental que mapeia URLs para ações específicas em sua aplicação. Quando um usuário acessa , o router é responsável por identificar qual código deve ser executado. Em frameworks modernos como Laravel ou Symfony, esse processo é automatizado, mas entender como criar um router do zero é essencial para compreender a arquitetura web e desenvolver soluções customizadas. Um router bem estruturado oferece controle total sobre sua aplicação, melhora a manutenção do código e permite implementar padrões avançados como RESTful APIs com facilidade. Vamos construir um router simples, mas robusto, que você poderá usar em projetos pequenos ou expandir conforme suas necessidades crescerem. Fundamentos: Como um Router Funciona Capturando a URL e o Método HTTP Todo router começa capturando a URL solicitada e o método HTTP utilizado. Em PHP, isso é feito através de variáveis superglobais. O primeiro passo é extrair o caminho da URL e remover parâmetros

<h2>O que é Roteamento HTTP e Por Que Importa</h2>

<p>Roteamento HTTP é o mecanismo fundamental que mapeia URLs para ações específicas em sua aplicação. Quando um usuário acessa <code>exemplo.com/usuarios/123</code>, o router é responsável por identificar qual código deve ser executado. Em frameworks modernos como Laravel ou Symfony, esse processo é automatizado, mas entender como criar um router do zero é essencial para compreender a arquitetura web e desenvolver soluções customizadas.</p>

<p>Um router bem estruturado oferece controle total sobre sua aplicação, melhora a manutenção do código e permite implementar padrões avançados como RESTful APIs com facilidade. Vamos construir um router simples, mas robusto, que você poderá usar em projetos pequenos ou expandir conforme suas necessidades crescerem.</p>

<h2>Fundamentos: Como um Router Funciona</h2>

<h3>Capturando a URL e o Método HTTP</h3>

<p>Todo router começa capturando a URL solicitada e o método HTTP utilizado. Em PHP, isso é feito através de variáveis superglobais. O primeiro passo é extrair o caminho da URL e remover parâmetros de query:</p>

<pre><code class="language-php">&lt;?php

class Router {

private $routes = [];

public function __construct() {

$this-&gt;parseRequest();

}

private function parseRequest() {

$method = $_SERVER[&#039;REQUEST_METHOD&#039;];

$path = parse_url($_SERVER[&#039;REQUEST_URI&#039;], PHP_URL_PATH);

// Remove a barra final para padronizar

$path = rtrim($path, &#039;/&#039;) ?: &#039;/&#039;;

return [$method, $path];

}

}</code></pre>

<p>Este código extrai o método HTTP (GET, POST, PUT, DELETE) e o caminho limpo. A função <code>parse_url()</code> garante que parâmetros query sejam ignorados, mantendo apenas a estrutura da rota.</p>

<h3>Registrando Rotas</h3>

<p>Agora precisamos de um sistema para registrar rotas e associá-las a callbacks:</p>

<pre><code class="language-php">public function get($path, $callback) {

$this-&gt;routes[&#039;GET&#039;][$path] = $callback;

}

public function post($path, $callback) {

$this-&gt;routes[&#039;POST&#039;][$path] = $callback;

}

public function put($path, $callback) {

$this-&gt;routes[&#039;PUT&#039;][$path] = $callback;

}

public function delete($path, $callback) {

$this-&gt;routes[&#039;DELETE&#039;][$path] = $callback;

}</code></pre>

<p>Cada método HTTP recebe uma rota (caminho) e uma função (callback) que será executada quando essa rota for acessada. O callback pode ser uma função anônima ou uma string referenciando um controller.</p>

<h2>Implementação: Criando um Router Completo</h2>

<h3>Suportando Rotas Dinâmicas com Parâmetros</h3>

<p>Rotas estáticas são úteis, mas a maioria das aplicações precisa de parâmetros dinâmicos. Vamos adicionar suporte a <code>:id</code> e similares:</p>

<pre><code class="language-php">private function matchRoute($method, $path) {

// Verifica rota exata primeiro

if (isset($this-&gt;routes[$method][$path])) {

return [$this-&gt;routes[$method][$path], []];

}

// Verifica rotas com parâmetros

if (!isset($this-&gt;routes[$method])) {

return null;

}

foreach ($this-&gt;routes[$method] as $route =&gt; $callback) {

$pattern = preg_replace(&#039;/:[a-zA-Z_][a-zA-Z0-9_]*/&#039;, &#039;([^/]+)&#039;, $route);

$pattern = &#039;#^&#039; . $pattern . &#039;$#&#039;;

if (preg_match($pattern, $path, $matches)) {

array_shift($matches); // Remove a correspondência completa

// Extrai nomes dos parâmetros

preg_match_all(&#039;/:[a-zA-Z_][a-zA-Z0-9_]*/&#039;, $route, $params);

$params = array_map(fn($p) =&gt; substr($p, 1), $params[0]);

$params = array_combine($params, $matches);

return [$callback, $params];

}

}

return null;

}</code></pre>

<p>Este método usa regex para transformar rotas como <code>/usuarios/:id</code> em padrões capturáveis. Se encontrar uma correspondência, retorna o callback e um array com os parâmetros extraídos.</p>

<h3>Executando o Router</h3>

<p>Agora vamos adicionar o método que executa toda a lógica:</p>

<pre><code class="language-php">public function dispatch() {

[$method, $path] = $this-&gt;parseRequest();

$result = $this-&gt;matchRoute($method, $path);

if ($result === null) {

http_response_code(404);

echo &quot;Rota não encontrada: $method $path&quot;;

return;

}

[$callback, $params] = $result;

// Se for string, assume que é um controller@action

if (is_string($callback)) {

[$class, $action] = explode(&#039;@&#039;, $callback);

$controller = new $class();

echo $controller-&gt;$action($params);

} else {

// Se for closure ou função

echo call_user_func_array($callback, array_values($params));

}

}</code></pre>

<h2>Exemplo Prático: Usando o Router</h2>

<h3>Aplicação Completa Funcionando</h3>

<pre><code class="language-php">&lt;?php

// Arquivo: router.php - Contém a classe Router completa

$router = new Router();

// Rotas simples

$router-&gt;get(&#039;/&#039;, function() {

return &quot;Bem-vindo à página inicial!&quot;;

});

// Rotas com parâmetros

$router-&gt;get(&#039;/usuarios/:id&#039;, function($id) {

return &quot;Visualizando usuário ID: $id&quot;;

});

// Rotas POST

$router-&gt;post(&#039;/usuarios&#039;, function() {

return &quot;Novo usuário criado!&quot;;

});

// Usando controllers (string)

$router-&gt;get(&#039;/posts/:id&#039;, &#039;PostController@show&#039;);

$router-&gt;dispatch();</code></pre>

<p>Se você tiver um <code>PostController.php</code>:</p>

<pre><code class="language-php">&lt;?php

class PostController {

public function show($params) {

$id = $params[&#039;id&#039;];

return &quot;Exibindo post: $id&quot;;

}

}</code></pre>

<h2>Conclusão</h2>

<p>Aprendemos que um router eficaz repousa em três pilares: <strong>captura correta da requisição HTTP</strong>, <strong>armazenamento inteligente de rotas com suporte a parâmetros</strong> e <strong>execução flexível de callbacks</strong>. Um router simples como este é suficiente para aplicações MVP ou APIs REST básicas, servindo como fundação para entender como frameworks profissionais funcionam. Para produção, considere usar soluções estabelecidas, mas nunca subestime o valor de implementar um router from scratch para consolidar seu conhecimento.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://www.php.net/manual/en/reserved.variables.server.php" target="_blank" rel="noopener noreferrer">PHP Manual: $_SERVER Superglobal</a></li>

<li><a href="https://www.php-fig.org/psr/psr-7/" target="_blank" rel="noopener noreferrer">PSR-7: HTTP Message Interface</a></li>

<li><a href="https://github.com/nikic/FastRoute" target="_blank" rel="noopener noreferrer">FastRoute: Roteador de Alto Desempenho</a></li>

<li><a href="https://laravel.com/docs/routing" target="_blank" rel="noopener noreferrer">Laravel Routing Documentation</a></li>

<li><a href="https://www.php.net/manual/en/intro.http.php" target="_blank" rel="noopener noreferrer">RESTful APIs com PHP</a></li>

</ul>

Comentários

Mais em PHP

Dominando Headers HTTP em PHP: Redirecionamentos e Respostas em Projetos Reais
Dominando Headers HTTP em PHP: Redirecionamentos e Respostas em Projetos Reais

Headers HTTP em PHP: Redirecionamentos e Respostas O Que São Headers HTTP e P...

Dominando Construtores, Destrutores e Métodos em PHP em Projetos Reais
Dominando Construtores, Destrutores e Métodos em PHP em Projetos Reais

Construtores em PHP O construtor é um método especial executado automaticamen...

Como Usar Conexão com MySQL usando PDO em PHP em Produção
Como Usar Conexão com MySQL usando PDO em PHP em Produção

Introdução ao PDO: Por que usar? PDO (PHP Data Objects) é uma abstração de ba...