decodelabs/greenleaf

基于目录的超级快速HTTP路由器

v0.3.0 2024-08-22 02:46 UTC

This package is auto-updated.

Last update: 2024-09-04 21:14:43 UTC


README

PHP from Packagist Latest Version Total Downloads GitHub Workflow Status PHPStan License

基于目录的超级快速HTTP路由器

Greenleaf提供了一种简单、快速且灵活的方式来根据URL路径将HTTP请求路由到控制器和操作。

DecodeLabs博客上获取新闻和更新。

安装

通过Composer安装

composer require decodelabs/greenleaf

用法

Greenleaf提供了一个PSR-15中间件,可以与任何PSR-15兼容的框架一起使用。它将解析请求路径,并尝试将其与一组配置的路由进行匹配。

Greenleaf的核心是一个基于目录的类映射,它可以从一个与大多数Web应用逻辑结构更接近的目录树中加载GeneratorsRoutesActions

您需要至少在Greenleaf中注册一个命名空间,以便它可以从您配置的目录树中加载类。

use DecodeLabs\Greenleaf;

Greenleaf::$namespaces->add('MyApp\\Greenleaf');

分发器

Greenleaf通过Harvest Middleware命名空间提供其分发器,以便与Harvest轻松集成并自动解析类。

但是,您可以直接实例化分发器并将其视为标准PSR HTTP处理器。

use DecodeLabs\Greenleaf;
use DecodeLabs\Harvest;

$dispatcher = Greenleaf::createDispatcher();

$request = Harvest::createRequestFromEnvironment();
$response = $dispatcher->handle($request);

生成器

生成器用于加载和配置路由。它们是实现了Generator接口的简单类。

默认情况下,Greenleaf将加载一个Scanner生成器,它将扫描配置的目录树中的其他生成器,并加载它们提供的操作。

要在您的目录树中定义路由,您可以从通用路由生成器开始。

namespace MyApp\Greenleaf;

use DecodeLabs\Greenleaf;
use DecodeLabs\Greenleaf\Generator;
use DecodeLabs\Greenleaf\GeneratorTrait;

class Routes implements Generator
{
    use GeneratorTrait;

    public function generateRoutes(): iterable
    {
        // Basic route
        yield Greenleaf::route('/', 'home');

        // Basic route with parameter
        yield Greenleaf::route('test/{slug}', 'test')

        // Route with inset parameters
        yield Greenleaf::route('test-{slug}/', 'test?hello')
            ->with('slug', validate: 'slug');

        // Route with multi-part path parameters
        yield Greenleaf::route('assets/{path}', 'assets')
            ->with('path', validate: 'path');

        // Redirect
        yield Greenleaf::redirect('old/path', 'new/path');
    }
}

路由器

当分发器运行时,它会加载一个合适的路由器来处理将请求与配置的路由进行匹配。

在此早期阶段,Greenleaf提供了一个参考匹配实现,它只是通过暴力方式遍历路由列表直到找到匹配项。这个实现还没有针对速度进行优化,将很快被一个高性能编译路由器系统所取代,它可以轻松处理数千个路由。

当路由器实现找到一个匹配项时,它会将路由模式转换为Greenleaf自定义URI和一组参数,然后将这些参数传递给操作(如果相关)。

Greenleaf URI

URI格式主要是HTTP URL的子集,其中leaf作为方案,标准路径、查询和片段组件,还有一个值得注意的补充:areas

由路径中的第一个元素为~表示的区域允许应用程序轻松划分分离的区域(如前端和管理员)。

默认区域是"front",在未指定区域时使用。

例如

// Route
Greenleaf::route('test/{slug}', 'test?hello');

// Creates URI
Greenleaf::uri('leaf://~front/test?hello');
// $params = ['slug' => 'value-of-slug-in-request']

// Resolves to:
$actionClass = MyApp\Greenleaf\Front\TestAction::class;

// --------------------------
// Or
Greenleaf::route('admin/blog/articles', '~admin/blog/articles');

// Creates URI
Greenleaf::uri('leaf://~admin/blog/articles');

// Resolves to:
$actionClass = MyApp\Greenleaf\Admin\Blog\ArticlesAction::class;

操作

一旦加载,操作必须仅实现一个execute($request, $uri, $params)方法,然而Greenleaf提供了一些特质,可以用来添加额外功能。

例如,ByMethodTrait将尝试根据请求的HTTP方法在操作上调用方法。

请注意,大多数以此方式工作的特质将使用Slingshot进行方法调用,并提供深度依赖注入支持。在此示例中,匹配的路由请求URL中的slug作为字符串传递给操作处理程序。

namespace MyApp\Greenleaf\Front;

use DecodeLabs\Harvest;
use DecodeLabs\Harvest\Response;
use DecodeLabs\Greenleaf;
use DecodeLabs\Greenleaf\Action;
use DecodeLabs\Greenleaf\Action\ByMethodTrait;

class TestAction implements Action
{
    use ByMethodTrait;

    public function get(string $slug): Response {
        return Harvest::text('Get response');
    }

    public function post(string $slug): Response {
        return Harvest::text('Post response');
    }
}

URL

Greenleaf的主要优势之一是,它允许您通过创建带有许多已设置所需URL结构的leaf URI,以简单灵活的方式生成路由的URL。

然后,路由器能够将这些URI与正确的路由匹配,并将参数传递给URL生成器。

use DecodeLabs\Greenleaf;

// route pattern: test/{slug}

$url = Greenleaf::createUrl(
    'test?hello#fragment',
    ['slug' => 'my-slug']
);

// https://mydomain.localtest.me/test/my-slug?hello#fragment

许可

Greenleaf采用MIT许可证。请参阅LICENSE获取完整的许可文本。