azjezz/hack-routing

快速、类型安全的请求路由、参数检索和链接生成。

dev-main 2021-06-10 18:37 UTC

This package is auto-updated.

Last update: 2024-09-11 01:49:14 UTC


README

Unit tests status Static analysis status Coding standards status Type Coverage Total Downloads Latest Stable Version License

快速、类型安全的请求路由、参数检索和链接生成。

这是Facebook, Inc.的hack-router的移植。

组件

HTTP 异常

表示HTTP应用程序中常见情况的异常类

  • HackRouting\HttpException\InternalServerErrorException
  • HackRouting\HttpException\MethodNotAllowedException
  • HackRouting\HttpException\NotFoundException

路由器

一个简单的类型化请求路由器。示例

<?php

use Psl\Str;
use HackRouting\Cache;
use HackRouting\Router;
use HackRouting\HttpMethod;
use HackRouting\HttpException;

$cache = new Cache\ApcuCache();
$router = new Router($cache);

$router->addRoute(HttpMethod::GET, '/', function (): string {
    return 'Hello, World!';
});

$router->addRoute(HttpMethod::GET, '/user/{username:[a-z]+}', function (array $parameters): string {
    return Str\format('Hello, %s!', $parameters['username']);
});

$router->addRoute(HttpMethod::POST, '/', function (): string {
    return 'Hello, POST world';
});

$router->addRoute(HttpMethod::GET, '/{page:about|contact}-us', static function (array $parameters): string {
    if ($parameters['page'] === 'about') {
        return 'Learn about us';
    }

    return 'Contact us';
});


try {
    [$responder, $parameters] = $router->match('GET', '/user/azjezz');
    
    $responder($parameters); // Hello, azjezz!
} catch (HttpException\MethodNotAllowedException $e) {
    $allowed_methods = $e->getAllowedMethods();
    // Handle 405.
} catch (HttpException\NotFoundException) {
    // Handle 404.
} catch (HttpException\InternalServerErrorException) {
    // Handle 500.
}

AbstractRouter

一个更底层的路由器,允许您使用其他方式(例如从配置文件)加载路由。

<?php

use Psl\Str;
use HackRouting\AbstractRouter;
use HackRouting\HttpMethod;

/**
 * @extends BaseRouter<(function(array<string, string>):string)>
 */
final class Matcher extends AbstractRouter {
  /**
   * @return array<non-empty-string, array<string, (function(array<string, string>):string)>>
   */
  protected function getRoutes(): array {
    return [
      HttpMethod::GET => [
        '/' => static fn(array $parameters): string => 'Hello, World!',
        '/user/{username}/' => static fn(array $parameters): string => Str\format('Hello, %s!', $parameters['username']),
      ],

      HttpMethod::POST => [
        '/' => static fn(array $parameters): string => 'Hello, POST world',
      ],
    ];
  }
}

为了简洁,进行了简化 - 请参阅examples/AbstractRouterExample.php以获取完整可执行示例。

UriPatterns

以一致和类型安全的方式生成路由片段、URI(用于链接)和检索URI参数

<?php

use HackRouting\UriPattern\UriPattern;

final class UserPageController extends WebController {
  public static function getUriPattern(): UriPattern {
    return (new UriPattern())
      ->literal('/users/')
      ->string('user_name');
  }

  // ...
}

可以检索参数,并在运行时同时根据值和定义进行类型检查

public function getResponse(): string {
  return 'Hello, '.$this->getUriParameters()->getString('user_name');
}

您还可以生成到控制器的链接

$link = UserPageController::getUriBuilder()
  ->setString('user_name', 'Mr Hankey')
  ->getPath();

为了简洁,以下示例进行了简化 - 请参阅examples/UriPatternsExample.php以获取完整可执行示例。

缓存

HackRouting自带4种缓存策略。

  • HackRouting\Cache\ApcuCache
  • HackRouting\Cache\FileCache
  • HackRouting\Cache\MemoryCache
  • HackRouting\Cache\NullCache

默认情况下,路由器将使用NullCache策略,但是在生产中,强烈建议使用适合您需求的另一种策略。

如果您的应用程序在传统的Web服务器(例如:fpm/fast-cgi)后面运行,如果可能,建议使用ApcuCache策略,否则回退到FileCache

如果您的应用程序与长时间运行的过程服务器(如Amphp、ReactPHP、RoadRunner等)一起使用,建议使用MemoryCache以避免额外的I/O操作并最大化性能。

贡献

我们欢迎GitHub问题和拉取请求 - 请参阅CONTRIBUTING.md以获取详细信息。

许可

hack-routing遵循MIT许可。