albreis / router
Requires
- php: >=8.1
- albreis/phptest: ^1.2
This package is auto-updated.
Last update: 2025-03-15 01:04:34 UTC
README
Antes de tudo precisamos importar nosso loader do composer:
include 'vendor/autoload.php;
Agora podemos instânciar o Router.
$router = new \Albreis\Router; // ou use Albreis\Router; $router = new Router;
Fazendo uma requisição
O Router aceita qualquer método de requisição e possui 3 argumentos:
$router->[metodo]([path], [callback], [bypass], [return]);
metodo GET, POST, DELETE, CLI, etc
path é o caminho em que o callback deve ser executado. Usa REGEX para definir as rotas.
callback é um callable, seja uma função ou método e aceita os formatos:
- função anônima
function() { ... }
- métodos
[$instancia, metodo]
Ex. [$this, run] - métodos estáticos
'Classe::metodo'
(caso não seja estático será criada uma instância da classe automaticamente) - Arrow functions
fn() => return true
bypass indica se o script vai continuar sendo executado após o match com a rota.
return indica se será retornado o valor caso o callback retorne algum valor
Exemplos
Exemplo 1:
$router->get('^login$', function(){ /** * Aqui tu podes criar toda sua lógica seja retornar * um JSON ou um HTML **/ });
Exemplo 2:
$router->get('^([^/]+)/([^/]+)$', function($category, $post){ /** * Aqui tu podes criar toda sua lógica seja retornar * um JSON ou um HTML **/ });
O Router chamará a função exit()
após executar o callback, evitando assim a execução do restante do script.
Caso queira que o script continue sendo executado mesmo após dar match com a rota basta passar o parâmetro bypass como true.
Exemplo 3:
$router->get('^([^/]+)/([^/]+)$', function($category, $post){ /** * Ao acessar a URL /frutas/melancia * A saída do var_dump abaixo seria: * string(6) "frutas" string(8) "melancia" */ var_dump($category, $post); /** * Essa rota vai ser executada e continuar para * a próxima rota pois foi passado o parâmetro 3 como true */ }, true);
Ao acessar a rota http://seusite.com.br/minha-categoria/postagem-109 as variáveis $category
e $post
teriam os valores minha-categoria e postagem-109 respectivamente.
Como criar um middleware
Para usar o Router como um middleware para setar a rota como bypass.
No exemplo abaixo temos um middleware que é executado em todas as requisições do método POST para a rota login.
Um exemplo de uso seria para criar um sistema de logs de requisição ou pré tratamento de dados.
Exemplo 4:
$router->get('^login$', function(){ /** * Executa as instruções e segue para a próxima rota */ /** * Este print_r() irá retornar Array ( ) */ print_r($_GET); $_GET['teste'] = 123; }, true); $router->get('^login$', function(){ /** * Daqui em diante nada será executado */ /** * Este print_r() irá retornar Array ( [teste] => 123 ) */ print_r($_GET); });
Before e After
Existem 2 métodos que também podem ser utilizados com middlwares.
A diferença entre usar esses métodos ou utilizar uma rota com bypass é que com before e after você não precisa escrever o pattern da rota.
Before e After podem ser usados também em rotas com bypass.
$router->before(function(){ /** * Callback executado antes da action da rota */ })->after(function(){ /** * Callback executado após a action da rota */ })->get('^login$', function(){ /** * Executa as instruções da rota e pára a excusão do script */ /** * Este print_r() irá retornar Array ( ) */ print_r($_GET); $_GET['teste'] = 123; });
Usando via CLI
Você pode usar o Router via terminal para chamar as rotas usando o padrão abaixo:
$ php index.php METODO PATH ARGUMENTOS
Exemplo:
$ php index.php POST /login username=usuario01 password=1234
Exemplos avançados
Exemplo 5 (funções anônimas):
$router->get('^login$', function(){ });
Exemplo 6 (arrow functions):
$router->get('^([^/]+)/([^/]+)$', fn($a, $b) => var_dump($a, $b));
Exemplo 6 (métodos):
class Home { public function index($a, $b) { echo 'Homepage'; } } $home = new Home; $router->get('^([^/]+)/([^/]+)$', [$home, 'index']); // ou $router->get('^([^/]+)/([^/]+)$', 'Home::index'); // ou $router->get('^([^/]+)/([^/]+)$', function($a, $b) use ($home) { $home->index($a, $b); }); // ou $router->get('^([^/]+)/([^/]+)$', fn($a, $b) => $home->index($a, $b));
Prefix
Agora é possível agrupar rotas usando prefixos:
Exemplo:
$router->prefix('/api')->all(function(Router $router) { $router->get('^([^/]+)/([^/]+)$', [$home, 'index']); // ou $router->get('^([^/]+)/([^/]+)$', 'Home::index'); // ou $router->get('^([^/]+)/([^/]+)$', function($a, $b) use ($home) { $home->index($a, $b); }); // ou $router->get('^([^/]+)/([^/]+)$', fn($a, $b) => $home->index($a, $b)); });
Agora os métodos podem usar injeção de parâmetro, exemplo:
$router = new Albreis\Router; class Model { } $router->get('/', function(Model $model){ // $model é uma instância da classe Model });
Agora também é possivel acessar uma instância do Router a partir do método:
$router = new Albreis\Router; $router->get('/', function($router){ // $router é uma instância do router atual e está sempre disponível });
Usando Registry
Router Registry é uma forma de carregar automaticamente rotas usando DocBlock @Route.
Exemplo:
class HomeController { /** * @Route::get('^/?$') */ public function index() { var_dump(123); } }
Como carregar automaticamente arquivos:
<?php use Albreis\Router; use Albreis\RouterRegistry; require '../vendor/autoload.php'; $router = new Router; $registry = new RouterRegistry($router); $registry->loadFrom(__DIR__ . '/../src/Http/Controllers', 'App/'); $registry->run();
Isso vai fazer com o todas as classes do namespace App/ do diretorio sejam mapeadas.
Como carregar uma classe única:
<?php use Albreis\Router; use Albreis\RouterRegistry; use App\Http\Controllers\HomeController; require '../vendor/autoload.php'; $router = new Router; $registry = new RouterRegistry($router); $registry->addClass(HomeController::class); $registry->run();
Isso vai fazer com os metodos da classe sejam mapeados.
Usando funções:
Você pode utilizar funções para trabalhar com rotas:
<?php use Albreis\Router; use Albreis\RouterRegistry; use App\Http\Controllers\HomeController; require '../vendor/autoload.php'; $router = new Router; $registry = new RouterRegistry($router); /** * @Route::get('/hello') */ function hello() { echo('hello'); } $registry->loadUserFunctions(); $registry->run();
Ao acessar /hello o Router vai executar essa função. Lembre-se que a função precisa existir.
Caso a função esteja em um arquivo externo que ainda não tenha sido feito include/require vocêpode usar o método loadUserFunctionsFrom(), ele vai fazer include do arquivo antes de buscar rotas.
<?php use Albreis\Router; use Albreis\RouterRegistry; use App\Http\Controllers\HomeController; require '../vendor/autoload.php'; $router = new Router; $registry = new RouterRegistry($router); $registry->loadUserFunctionsFrom('../functions.php'); $registry->run();
Adicionar uma função unica
<?php use Albreis\Router; use Albreis\RouterRegistry; use App\Http\Controllers\HomeController; require '../vendor/autoload.php'; $router = new Router; $registry = new RouterRegistry($router); /** * @Route::get('/hello') */ function hello() { echo('hello'); } $registry->addFunction('hello'); $registry->run();
Salvar rotas em arquivo para produção
Em produção o ideal é que a aplicação não fique escaneando os arquivos por rotas a cada requisição.
Para isso você pode gerar um arquivo de rotas usando o método $registry->save([caminho do arquivo]).
O caminho padrão do arquivo é routes.php no direotrio atual.