henriquebs0/router

dev-main 2022-01-29 21:34 UTC

This package is auto-updated.

Last update: 2024-09-28 21:59:56 UTC


README

PHP 组件,用于控制您的应用程序的路由。

PHP 组件,用于控制您应用程序的路由。

安装

Composer

composer require henriquebs0/router dev-main

路由

要开始管理路由,只需在应用程序中所有请求都经过的中心点(例如,文件 index.php)处实例化 Router(string $baseUri = '/') 类的对象,添加路由,然后调用 resolve() 方法。

htaccess

RewriteEngine On

# ROUTER URL Rewrite
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L,QSA]

index.php

<?php

require_once __DIR__ . '/vendor/autoload.php';

use HenriqueBS0\Router\Router;

/**
 * Instantiating the object
 */
$router = new Router();

/**
 * Adding a route to the '/' path
 */
$router->get('/', function() {
    echo 'Hello World!';
});

/**
 * Resolves the process and forwards to the route
 */
$router->resolve();

添加路由

添加路由有五种方法,这些方法直接与 HTTP 方法相关,分别是

  • get($path, $callback, $middlewaresClasses): void

  • post($path, $callback, $middlewaresClasses): void

  • put($path, $callback, $middlewaresClasses): void

  • patch($path, $callback, $middlewaresClasses): void

  • delete($path, $callback, $middlewaresClasses): void

    • string $path: 将被访问的路径。
    • callable|array $callback: 要执行的功能。
    • array $middlewaresClasses: 中间件类。
<form method="POST">
    <label for="_method">Method</label>
    <select name="_method" id="_method">
        <option value="GET">GET</option>
        <option value="POST">POST</option>
        <option value="PUT">PUT</option>
        <option value="PATCH">PATCH</option>
        <option value="DELETE">DELETE</option>
    </select>
    <input type="submit" value="Send">
</form>
<?php

require_once __DIR__ . '/vendor/autoload.php';

use HenriqueBS0\Router\Router;

class Controller {
    public function get() {
        echo "GET";
    }

    public function post() {
        echo "POST";
    }

    public function put() {
        echo "PUT";
    }

    public function patch() {
        echo "PATCH";
    }

    public function delete() {
        echo "DELETE";
    }
}

$router = new Router();

$router->get('/', [Controller::class, 'get']);
$router->post('/', [Controller::class, 'post']);
$router->put('/', [Controller::class, 'put']);
$router->patch('/', [Controller::class, 'patch']);
$router->delete('/', [Controller::class, 'delete']);

$router->resolve();

注意,存在一个保留参数 _method,这是因为 HTML5 表单仅支持 GETPOST 方法。

URL 参数

要告知期望参数,请将此参数的名称放在花括号内,这些将被按顺序传递给路由回调。

<?php

require_once __DIR__ . '/vendor/autoload.php';

use HenriqueBS0\Router\Router;

class Controller {
    public function user($id) {
        echo "User id - {$id}";
    }
}

$router = new Router();

/**
 * Expect to receive the 'id' parameter
 */
$router->get('/user/{id}', [Controller::class, 'user']);

$router->resolve();

分组

为了简化告知路径的过程,存在一个 group(string $group) 方法,该方法为所有后续告知的路由设置基本路径。就像前面的例子使用这个功能。

<?php

require_once __DIR__ . '/vendor/autoload.php';

use HenriqueBS0\Router\Router;

class Controller {
    public function user($id) {
        echo "User id - {$id}";
    }
}

$router = new Router();

$router->group('/user');

$router->get('/{id}', [Controller::class, 'user']);

$router->resolve();

未找到

当访问的 URL 与任何路由不匹配时,会触发默认方法,它将请求状态设置为 404,然后打印此值。要更改此行为,可以使用 setNotFound(callable|array $callback) 方法。

<?php

require_once __DIR__ . '/vendor/autoload.php';

use HenriqueBS0\Router\Router;

$router = new Router();
$router->setNotFound(function() {
    echo 'Not Found.';
});
$router->resolve();

中间件

中间件是一种检查到达您应用程序的请求的方式。要创建中间件,只需创建一个扩展 Middleware 的类。

<?php

use HenriqueBS0\Router\Middleware;

class MiddlewareExample extends Middleware {
    public function checks(): bool
    {
        return true;
    }

    public function invalidated(): void
    {
        echo 'Not authorized';
    }
}

上述类由两个方法组成,checks() 用于检查请求是否授权,以及 invalidated(),当请求未授权时(当 checks() 返回 false)执行。

关联中间件

中间件可以直接与路由关联,也可以以一般方式关联。在以一般方式添加中间件后,所有后续添加的路由都将考虑它。

<?php

require_once __DIR__ . '/vendor/autoload.php';

use HenriqueBS0\Router\Middleware;
use HenriqueBS0\Router\Router;

class MiddlwareGeneralOne extends Middleware {}
class MiddlwareGeneralTwo extends Middleware {}

class MiddlwareRouteOne extends Middleware {}
class MiddlwareRouteTwo extends Middleware {}

$router = new Router();

/**
 * Linking middleware in general
 * All routes added after this action will consider middlewares
 * 'MiddlwareGeneralOne' and 'MiddlwareGeneralTwo'
 */
$router->setMiddlewares([
    MiddlwareGeneralOne::class,
    MiddlwareGeneralTwo::class
]);

/**
 * Binding middleware specifically to route
 */
$router->get('/', function() {
    echo 'Hello World';
}, [MiddlwareRouteOne::class, MiddlwareRouteTwo::class]);

$router->resolve();

处理关联中间件的一般方法

  • setMiddlewares(array $middlewaresClasses): void
  • addMiddleware(string $middlewareClass): void
  • clearMiddlewares(): void
<?php

require_once __DIR__ . '/vendor/autoload.php';

use HenriqueBS0\Router\Middleware;
use HenriqueBS0\Router\Router;

class MiddlwareOne extends Middleware {}
class MiddlwareTwo extends Middleware {}
class MiddlwareThree extends Middleware {}
class MiddlwareFour extends Middleware {}

$router = new Router();

/**
 * Define that the middlewares applied will be
 * 'MiddlwareOne' and 'MiddlwareTwo'
 */
$router->setMiddlewares([
    MiddlwareOne::class,
    MiddlwareTwo::class
]);

/**
 * Clear all general middleware,
 * ie no middleware will be applied
 */

$router->clearMiddlewares();

/**
 * Add general middleware 'MiddlwareThree' and 'MiddlwareFour'
 */

 $router->addMiddleware(MiddlwareThree::class);
 $router->addMiddleware(MiddlwareFour::class);

 /**
  * According to flow the 'MiddlwareThree' and 'MiddlwareFour'
  * middleware will be linked to the route
  */
$router->get('/', function() {
    echo 'Hello World';
});

$router->resolve();

路由分组

为了使代码更加组织化,可以将路由分离到类中,然后使用 addRoutesGroup(string $routesGroupClass) 方法将这些路由分组添加到 Router 类的实例中。这些路由分组类必须扩展 RoutesGroup 类。

<?php

require_once __DIR__ . '/vendor/autoload.php';

use HenriqueBS0\Router\Middleware;
use HenriqueBS0\Router\Router;
use HenriqueBS0\Router\RoutesGroup;

class MiddlewareGeneral extends Middleware {};
class MiddlewareRoutesUser extends Middleware{};

class ControllerUser {
    public function userGet($id) {
        echo "User - {$id} | GET";
    }

    public function userPost() {
        echo 'User | POST';
    }

    public function userPut($id) {
        echo "User - {$id} | PUT";
    }

    public function userPatch($id) {
        echo "User - {$id} | PATCH";
    }

    public function userDelete($id) {
        echo "User - {$id} | DELETE";
    }
}

/**
 * Class with route group
 */

class RoutesUser extends RoutesGroup {

    /**
     * Reserved method for adding routes
     */
    protected function setRoutes(): void
    {
        $this->group('/user');

        $this->setMiddlewares([MiddlewareRoutesUser::class]);

        $this->get('/{id}', [ControllerUser::class, 'userGet']);
        $this->post('/', [ControllerUser::class, 'userPost']);
        $this->put('/{id}', [ControllerUser::class, 'userPut']);
        $this->patch('/{id}', [ControllerUser::class, 'userPatch']);
        $this->delete('/{id}', [ControllerUser::class, 'userDelete']);
    }
}

$router = new Router();

$router->get('/', function() {
    echo 'Hello World!';
});

/**
 * Adding general middleware
 */
$router->addMiddleware(MiddlewareGeneral::class);

/**
 * Adding a generic group
 */
$router->group('/generic');

/**
 * Adding route group
 */
$router->addRoutesGroup(RoutesUser::class);

$router->resolve();

请注意,扩展 RoutesGroup 的类有保留方法 setRoutes(),其中必须定义路由。与 RoutesGroup 类具有相同目的的方法,它们是

  • get($path, $callback, $middlewaresClasses): void
  • post($path, $callback, $middlewaresClasses): void
  • put($path, $callback, $middlewaresClasses): void
  • patch($path, $callback, $middlewaresClasses): void
  • delete($path, $callback, $middlewaresClasses): void
  • group(string $group): void
  • setMiddlewares(array $middlewaresClasses): void
  • addMiddleware(string $middlewareClass): void
  • clearMiddlewares(): void

与路由分组关联的外部通用中间件,如示例 MiddlewareGeneral

setRoutes 方法的作用域内,group 方法不会干扰 Router 类实例的 group 方法,反之亦然。

示例项目: Link Pack

许可证

麻省理工学院许可证(MIT)。请参阅许可证文件获取更多信息。