rgjoni / router

最小路由包

1.0.6 2020-12-27 23:49 UTC

This package is not auto-updated.

Last update: 2024-09-30 04:24:39 UTC


README

license release last-commit packagist

路由器

这是一个小型路由包,专注于关注点分离和逻辑模块化,同时保持实现足够简单。

从需要有一个HTTP路由器来与我的API的项目使用开始,这个项目迅速变成了一次关于面向对象编程和HTTP规范的大学习经历。

目录

  1. 路由
  2. 静态路由,工作流程
  3. 动态路由
  4. 子路由(分组)
  5. 处理
  6. HEAD请求
  7. 错误
  8. 致谢
  9. 贡献

安装

composer require rgjoni/router

命名空间

Gjoni\Router

依赖项

先决条件

  • PHP 7.4或更高版本
  • 一个具有(最好是)引导能力的入口脚本(例如 index.php
  • 服务器配置将所有请求指向入口脚本 - 示例请参考这里

支持的方法

GET, HEAD, POST, PUT, PATCH, DELETE

路由

该库提供静态和动态路由(使用占位符),以及子路由(路由分组),同时利用Controller@method注解和回调作为处理程序。

控制器映射,自定义404回调和JSON错误处理也包含在包中。

设置控制器映射

在使用“Controller@method”注解的情况下,默认命名空间映射设置为App\Controllers(其中可能只有一个)。如果您想使用自己的,可以覆盖它(在工作流程中的第一件事)。

Router::setMap("MyAppNamespace\Controllers");

静态路由和工作流程

require_once dirname(__DIR__) . "/bootstrap.php";

use Gjoni\Router\Router;

Router::get("/about", $handler);

Router::run();

这就是使用工作流程的全部内容 - 使用所需的方法、路径和处理程序调用Router并运行它。

主页

use Gjoni\Router\Router;

Router::get("/", $handler);

动态路由

参数必须用大括号括起来({arg}),并且必须匹配以下正则表达式

[a-zA-Z0-9\_]+

使用方法

use Gjoni\Router\Router;

Router::get("/groups/{id}", $handler);

Router::run();

参数名(在这种情况下为id)不必与处理程序中的名称匹配。

多个参数示例

use Gjoni\Router\Router;

Router::get("/groups/{group_id}/meetups/{meetup_id}", $handler);

在具有多个参数的路由的情况下,参数名称必须不相互冲突,这是因为解析器的工作方式 - 它为每个参数创建一个数组键(使用其名称)。

子路由

当需要时,可以将路由捆绑在一起以用于特定部分,这很容易实现。

子路由必须使用group方法声明,并放置在回调函数内部 - 以下示例将构建预期的路由(例如,"/admin/settings")。

组名称必须以斜线(/)开头,以及子路由(在此示例中为settings等)。

use Gjoni\Router\Router;

Router::group("/admin", function() {
    Router::get("/", $handler);
    Router::get("/settings", $settingsHandler);
    Router::post("/settings/{id}", $updateHandler);
    Router::get("/users", $fetchUsersHandler);
});

嵌套子路由也是可能的,组将依次添加(例如,"/group1/group2/route")。

处理

如上所述,此路由器支持两种类型的处理

  • "Controller@method"

处理程序的前一部分(在@之前)必须只包括控制器名称,该名称必须位于命名空间中(请参阅命名空间部分)。

use Gjoni\Router\Router;

Router::group("/api", function() {
    Router::get("/auth/login", "AuthenticationController@login");
    Router::get("/user/{id}", "UserController@profile");
});

Router::run();

根据您如何处理命名空间,将创建控制器实例并调用方法,无论是否带有参数。

如果没有传递方法或输入了分隔符 @(例如 AuthenticationControllerlogin)的错误,则会抛出并处理异常;如果在命名空间中找不到类,则还会抛出另一个异常。

  • 匿名函数
use Gjoni\Router\Router;

Router::get("/me", function() {
    /** some cool user experience */
});

Router::post("/settings/{setting_name}", function($id) {
    /** some more magic */
});

Router::run();

HEAD请求

正如RFC2616 HTTP规范所暗示的,路由器将重定向 HEAD 请求到相同的匹配 GET 路由。

错误处理

所有错误都通过 JSON 形式处理并返回,是 error 键的值。

404 - 未找到

如果由于某种原因,路由器在声明中找不到路由,则会抛出一个默认的 404 错误。

{"error":"Route not found."}
自定义 404

如果想要处理自己的 404 错误,可以使用 setNotFound 方法和一个闭包来实现。

use Gjoni\Router\Router;

Router::setNotFound(function() {
    /** special error handling */
});

400 - 不允许的字符

如果 URL 与以下模式匹配:[^-:\/a-zA-Z\d],则会抛出“URL 中不允许的字符”错误。

405 - 方法不允许

如果在找到路由但请求不匹配的情况下,则会抛出 MethodNotAllowedException。

{"error":"Method not allowed."}

致谢

在我开始这个项目的时候,我对路由以及如何解决这个问题几乎一无所知。

只有在我阅读了以下库的代码、思考其中的模式并进行实验之后,我才能理解足够的内容并找到一个满足我需求且令我满意的解决方案。

贡献

欢迎提交拉取请求和问题,请参阅 CONTRIBUTORS.md

许可证

MIT