albreis / router
Requires
- php: >=8.1
- albreis/phptest: ^1.2
This package is auto-updated.
Last update: 2024-09-20 23:10:37 UTC
README
首先我们需要导入我们的loader到composer
include 'vendor/autoload.php;
现在我们可以实例化Router。
$router = new \Albreis\Router; // ou use Albreis\Router; $router = new Router;
进行一个请求
Router接受任何请求方法,并具有3个参数
$router->[metodo]([path], [callback], [bypass], [return]);
方法 GET, POST, DELETE, CLI等
路径 是回调需要执行的路径。使用REGEX定义路由。
回调 是一个可调用项,可以是函数或方法,并接受以下格式
- 匿名函数
function() { ... }
- 方法
[$instancia, metodo]
示例:[$this, run] - 静态方法
'Classe::metodo'
(如果不是静态的,将自动创建类的实例) - 箭头函数
fn() => return true
bypass 表示脚本在匹配路由后是否继续执行。
return 表示当回调返回值时是否返回值。
示例
示例1
$router->get('^login$', function(){ /** * Aqui tu podes criar toda sua lógica seja retornar * um JSON ou um HTML **/ });
示例2
$router->get('^([^/]+)/([^/]+)$', function($category, $post){ /** * Aqui tu podes criar toda sua lógica seja retornar * um JSON ou um HTML **/ });
Router将在执行回调后调用exit()
函数,从而避免执行其余的脚本。
如果想在匹配路由后让脚本继续执行,只需将bypass
参数传递为true
。
示例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);
当访问路由 http://seusite.com.br/minha-categoria/postagem-109 时,变量 $category
和 $post
分别为 minha-categoria 和 postagem-109。
如何创建中间件
为了将Router用作设置路由为bypass
的中间件。
在下面的示例中,有一个中间件,它在所有针对login路由的POST请求中执行。
一个用例可能是创建一个请求日志系统或数据预处理系统。
示例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和After
有两种方法也可以与中间件一起使用。
使用这些方法或使用带有bypass的路由之间的区别在于,使用before和after,您不需要编写路由模式。
Before和After也可以用于带有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; });
通过CLI使用
您可以通过终端使用Router调用路由,使用以下模式
$ php index.php METODO PATH ARGUMENTOS
示例
$ php index.php POST /login username=usuario01 password=1234
高级示例
示例5(匿名函数)
$router->get('^login$', function(){ });
示例6(箭头函数)
$router->get('^([^/]+)/([^/]+)$', fn($a, $b) => var_dump($a, $b));
示例6(方法)
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));
前缀
现在可以通过前缀分组路由
示例
$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)); });
现在方法可以使用参数注入,例如
$router = new Albreis\Router; class Model { } $router->get('/', function(Model $model){ // $model é uma instância da classe Model });
现在也可以从方法中访问Router的实例
$router = new Albreis\Router; $router->get('/', function($router){ // $router é uma instância do router atual e está sempre disponível });
使用Registry
Router Registry是一种使用DocBlock @Route自动加载路由的方式。
示例
class HomeController { /** * @Route::get('^/?$') */ public function index() { var_dump(123); } }
如何自动加载文件
<?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();
这将使所有App/命名空间下的类都被映射。
如何加载单个类
<?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();
这将使类的所有方法都被映射。
使用函数
您可以使用函数来处理路由
<?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();
当访问/hello时,Router将执行这个函数。请记住,函数必须存在。
如果函数位于外部文件中,该文件尚未被include/require,您可以使用方法 loadUserFunctionsFrom()
,它会在查找路由之前包含文件。
<?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();
添加单个函数
<?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();
将路由保存到生产文件中
在生产中,理想的情况是应用每次请求时不要对文件进行路径扫描。
为此,您可以使用方法 $registry->save([文件路径]) 来生成一个路由文件。
默认的文件路径是当前目录下的 routes.php。