albreis/router

3.4.0 2024-09-20 23:10 UTC

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-categoriapostagem-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。