rammewerk/router

PHP简单路由器

0.7.0 2024-09-03 21:57 UTC

This package is auto-updated.

Last update: 2024-09-04 20:44:38 UTC


README

Rammewerk Router 是一个 PHP 路由库。它允许您管理您的 Web 应用程序中的路由,并包括类路由和自定义参数管理等功能。它还与自定义依赖注入系统兼容。它有助于创建动态和安全的路由系统,使新手和有经验的开发者都易于使用。

安装

使用 composer 安装 Rammewerk Router

composer require rammewerk/router

基于类的路由的基本用法

$router = new Rammewerk\Component\Router\Router();

$router->add('/', RouteActions::class);

$router->find();
class RouteActions {

    # Handle empty path as well as other unresolved paths.
    public function index(): void {
        echo 'Hello index';
    }
    
    # Handle paths that starts with '/blog/hello/'
    public function blog_hello(): void {
        echo 'Welcome to my blog!';
    }
      
}

在这个类中,任何不以 /blog/hello/ 开头的路径调用都将解析为 index 方法。

闭包

在其简单形式中,您可以使用闭包定义路由,就像许多其他 PHP 路由器一样

$router->add('/', function() {
    echo 'Hello index';
});

$router->add('/blog/hello', function() {
    echo 'Welcome to my blog!';
});

处理路由响应

如果您想集成响应处理器或类似功能,也可以从路由返回值。

$router->add('/', function(): string {
    return 'Hello index';
});

# Value will be whatever the route returns
$value = $router->find();

理解路径处理

路由器在路径处理方面有一个独特的方法,使其与传统 PHP 路由器区别开来。

路由映射机制

考虑对 URL /product/item/123 的请求。路由器通过尝试匹配整个路由来启动其搜索。如果不存在定义的路由 /product/item/123,则修改其搜索策略。

顺序裁剪和匹配

路由器从路径末尾开始裁剪,然后再次尝试匹配。它首先尝试找到 /product/item 的匹配项,然后是 /product,最后是 /,如果前面的尝试不成功。

这就是为什么在路由器开始查找路径之前,总是需要添加一个空路由 / 的原因。

参数捕获

路径中每个裁剪的段都被添加到参数列表中,其顺序与请求路径中的顺序相同。因此,如果路由 /product/item 是有效的,则 123 被捕获为第一个参数。

在代码中访问参数

为了更好地理解,以下是一个 PHP 示例,用于访问这些参数

$router->add('/product/item', function(string $id) {
    echo "Showing product item with ID: $id";
});

在这种情况下,当请求路由 /product/item/123 时,将 123 传递给 $id 参数。

处理不匹配的路由

请记住,如果需要像 $id 这样的参数,但请求中不包含它,路由器将认为路由不匹配。为了解决这个问题,只需通过设置默认值(如 string $id = '')使参数可选。这样,即使参数在请求中缺失,路由仍然有效。

配置路由

要添加新路由,您只需要定义路由及其对应的功能或类。下面是如何做的

$router->add('/page', function( ...$params ) {
    ...
})

请注意,在路由设置中不定义任何参数。相反,您提供的功能或类方法决定了它需要什么参数。当访问 '/page' 时,该功能或方法将使用它指定的参数运行。

以下是添加基于类的路由的示例

$router->add('/page', RouterActions::class )

处理不同类型的请求

路由器处理所有类型的 Web 请求(如 'GET' 或 'POST')。如果您需要根据请求类型做出不同的反应,可以创建一个包装器来完成这项工作。这有助于您根据不同的 Web 请求类型微调应用程序的行为。请记住,您需要了解 Web 请求类型以及如何设计响应,才能使用此功能。

处理依赖关系

您可以通过注册依赖注入容器来定义自定义处理依赖关系的方式

$router->registerDependencyLoader( function( string $class_name ) => use($container) {
    return $container->create($class_name);
});

注册后,它允许向其他类添加依赖关系

$router->add("/product/item/", function( ProductController $product, string $id ) {
    $product->showItem( $id );
});

请注意,第一个提供的字符串参数是从给定路径中提取的第一个参数。

基于类的路由

这个路由器独特之处在于,它可以根据其公共方法定义一个或多个处理路由的类。

它提供了一种快速处理路由的方法。

让我们定义一个简单的Route类,用于处理以/product/开头的所有路由

namespace Module\Product;

class ProductRouteActions {

    # Will handle /product/
    public function index(): void {
        echo 'Default product page when visiting base level of route: /';
    }
    
    # Will handle /product/item/{id}
    public function item( string $id ): void {
        echo "Implement loading of product item with id $id";
    }
    
    # Will handle /product/list/all/
    public function list_all(): void {
        echo "Implement list of all products"
    }
    
}

要注册这个类,我们可以这样定义

$router->add('/product', ProductRouteActions::class);

如果我们稍后想添加一个新的产品路由来处理产品更新,我们只需简单地在我们的类中添加一个新方法

class ProductRouteActions {

    ...
    
    # Will handle /product/update/{id}
    public function update( string $id ): void {
        # Handle product update for product of ID = $id
    }
    
}

设置自定义类加载器(可选)

可以自定义路由类如何处理其依赖项。这是通过使用在路由类开始初始化时运行的类依赖项加载器来完成的。

此加载器接收一个ReflectionClass对象,反映了正在加载的类。路由器已经创建了此ReflectionClass,为您节省了处理时间。此功能特别适用于模块化系统,用于检查类命名空间和加载正确的依赖项。

以下是注册自定义加载器的方法

$router->registerClassDependencyLoader( function( \ReflectionClass $class) use ($container) {
    return $container->create($class->name);
});

在这个例子中,$container->create($class->name);创建了这个类的实例。

注意:这是一个可选功能。如果您没有设置自定义类加载器,路由器将使用其默认加载器($router->registerDependencyLoader)。因此,即使没有自定义类加载器,您的路由类仍然会加载它们的依赖项。

设置路由认证

要添加在访问路由之前进行的认证检查,您可以定义一个默认方法。这个方法将在加载每个基于类的路由之前运行。

以下是注册默认方法的方法

$router->classAuthenticationMethod('hasRouteAccess');

现在,路由器将在加载任何基于类的路由之前运行'hasRouteAccess'方法(注意:这不适用于闭包路由)。此方法应返回truefalse,表示路由是否可访问。

class SecureBlogRoutes {

    // Access to any route in this class is granted if this returns true.
    public function hasRouteAccess(): bool {
        return ! empty($_SESSION['user_id']);
    }
    
    // This route will only load if 'hasRouteAccess' returns true.
    public function index(): void {
        echo 'Welcome to my secure blog!';
    }
    
}

一旦注册了默认认证方法,每个基于类的路由都必须实现它。如果一个路由类不需要认证,让它的'hasRouteAccess'方法返回true,这将允许所有请求通过。

您可以捕获RouteAccessDenied异常,并根据您的应用程序需求进行处理。例如,您可能希望将用户重定向到登录页面或显示错误消息,如果允许访问。

许可协议

本项目受MIT许可证许可 - 请参阅LICENSE文件以获取详细信息。

请注意,本项目“按原样”提供,不提供任何形式的保证,无论是明示的还是暗示的,包括但不限于,适销性和特定用途适用性的暗示保证。该项目质量和性能的全部风险由您承担。

支持

如果您有任何问题,请告诉我们。请发送电子邮件至support@rammewerk.com或创建一个问题。