decodelabs/greenleaf 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

decodelabs/greenleaf

Composer 安装命令:

composer require decodelabs/greenleaf

包简介

Super-fast directory based HTTP router

README 文档

README

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

Super-fast directory based HTTP router

Greenleaf provides a fast and flexible way to route HTTP requests to your actions and pages.

Installation

This package requires PHP 8.4 or higher.

Install via Composer:

composer require decodelabs/greenleaf

Usage

The main entry point to use Greenleaf is a PSR-15 middleware that can be used with any PSR-15 compatible framework, such as Harvest. It will parse the request and attempt to match it against a set of configured routes.

The system is comprised of a set of generators that can scan and find available routes, a collection of flexible route types and an extensible dispatcher architecture that allows for different matching strategies.

Dispatcher

While the dispatcher is usually accessed through middleware, you can if needed instantiate the Dispatcher directly and treat it as a standard PSR HTTP Handler.

use DecodeLabs\Harvest;
use DecodeLabs\Monarch;

$greenleaf = Monarch::getService(Greenleaf::class);
$harvest = Monarch::getService(Harvest::class);

$dispatcher = $greenleaf->createDispatcher();
$request = $harvest->createRequestFromEnvironment();
$response = $dispatcher->handle($request);

Namespace

The router will use Archetype to resolve Action classes from the URL - you can use Archetype's namespace mapping functionality to mount a directory for Http related classes:

use DecodeLabs\Archetype;
use MyApp\Http;

$archetype = Monarch::getService(Archetype::class);
$archetype->alias('DecodeLabs\\Greenleaf\\*', Http::class);

If your app is based on the Fabric framework, this mapping is taken care of for you automatically, based on the app namespace in your config.

Generators

Generators are used to load and configure routes. The Generator interface defines a simple mechanism for implementations to find and load routes.

By default, Greenleaf will load a Scanner Generator which in turn will scan the directory tree for other Generators and load the Actions they provide.

To define Routes in your directory tree, you can start with a generic Routes Generator which expects routes to be defined by hand:

namespace MyApp\Http;

use DecodeLabs\Greenleaf\Generator;
use DecodeLabs\Greenleaf\Route\Action;
use DecodeLabs\Greenleaf\Route\Parameter;
use DecodeLabs\Greenleaf\Route\Redirect;

class Routes implements Generator
{
    public function generateRoutes(): iterable
    {
        // Basic route
        yield new Action('/', 'home');

        // Basic route with parameter
        yield new Action('test/{slug}', 'test')

        // Route with inset parameters
        yield new Action('test-{slug}/', 'test?hello', parameters: [
            new Parameter\Slug('name')
        ])

        // Route with multi-part path parameters
        yield new Action('assets/{path}', 'assets', parameters: [
            new Parameter\Path('path')
        ]);

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

Router

When the Dispatcher runs, it loads an appropriate Router to take care of matching the request to the configured routes.

As of the current release, Greenleaf uses a generated switch based PatternSwitch Router that is extremely fast and efficient. There is also a CheckEach Router that runs a brute force loop over each route in turn - this is a very stable and predictable model, but is not recommended for production use.

When a Router implementation finds a match, it transforms the route pattern into a custom "leaf URL" in the format leaf:/path/to/file?query#fragment and a set of parameters that are then passed to the target of the route.

This is one of Greenleaf's biggest strengths as both input and output forms resolve to URL formats that can be easily looked up and matched against, both when matching in and when generating out.

Leaf URL

The URL format is mostly just a subset of HTTP URLs, with leaf as the scheme, standard path, query and fragment components.

For example:

// Route
new Action('test/{slug}', 'test?hello');

// Creates URL
$greenleaf->url('leaf:/test?hello');
// $parameters = ['slug' => 'value-of-slug-in-request']

// Resolves to:
$actionClass = MyApp\Http\Test::class;

// --------------------------
// Or
new Action('blog/articles', 'blog/articles');

// Creates URL
$greenleaf->url('leaf:/blog/articles');

// Resolves to:
$actionClass = MyApp\Http\Blog\Articles::class;

Routes

There are currently three types of route available in Greenleaf:

  • Action: A route that maps to an Action class. The action must implement the DecodeLabs\Greenleaf\Action interface and provides the most flexibility in responding to requests
  • Page: A route that maps to page components, in the same vein as the likes of Next.js. PageAction adapters handle loading different types of page content
  • Redirect: A route that redirects the request to a different URL. This is useful for handling legacy URLs or for redirecting to a different domain

Action

Actions need to implement an execute(DecodeLabs\Greenleaf\Request $request) method, and return a Response. Greenleaf provides a number of traits that can be used to add additional functionality and simplify writing logic for your views.

The ByMethodTrait for example will attempt to invoke a method on the Action based on the HTTP method of the request.

Note that most traits that work in this fashion will use Slingshot to invoke the method with deep dependency injection support. In this example, the slug from the matched route request URL is passed as a string to the action handlers.

namespace MyApp\Http;

use DecodeLabs\Harvest\Response\Text as TextResponse;
use DecodeLabs\Greenleaf\Action;
use DecodeLabs\Greenleaf\Action\ByMethodTrait;

class Test implements Action
{
    use ByMethodTrait;

    public function get(
        string $slug
    ): TextResponse {
        return new TextResponse('Get response');
    }

    public function post(
        string $slug
    ): TextResponse {
        return new TextResponse('Post response');
    }
}

Actions don't necessarily need to return PSR-7 responses directly - Greenleaf uses Harvest's response transformation system to convert all types of content responses to full PSR-7 HTTP responses.

Page

A page route is usually resolved to a content file or other type of component. Greenleaf provides a basic HTML file adapter that will load a file from the filesystem and return it as a response, however other packages provide more complex implementations, such as Horizon Page and Fragment component structures.

When a page route is matched, the file path is resolved using Monarch's path alias system, from a base path of @pages. This alias if not defined by your app, defaults to the @run/src/components/pages directory.

...

use DecodeLabs\Greenfleaf\Route\Page;

// HTML file /src/components/pages/about.html
yield new Page('about', 'about.html');

// Horizon Page /src/components/pages/blog.php
yield new Page('blog', 'blog.php');

HTTP URLs

One of the main benefits of Greenleaf is that it allows you to generate URLs for your routes in a simple and flexible way by creating leaf URLs with many of the required URL constructs already in place.

The router will then be able to match these URLs to the correct route and pass the parameters to the HTTP URL generator.

// route pattern: test/{slug}

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

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

Licensing

Greenleaf is licensed under the MIT License. See LICENSE for the full license text.

decodelabs/greenleaf 适用场景与选型建议

decodelabs/greenleaf 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.81k 次下载、GitHub Stars 达 1, 最近一次更新时间为 2023 年 11 月 09 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 decodelabs/greenleaf 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 decodelabs/greenleaf 我们能提供哪些服务?
定制开发 / 二次开发

基于 decodelabs/greenleaf 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 1.81k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 2
  • 点击次数: 11
  • 依赖项目数: 3
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 2
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-11-09