phoole/route 问题修复 & 功能扩展

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

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

phoole/route

Composer 安装命令:

composer require phoole/route

包简介

Slim, fast and full compatible PSR-7 & PSR-15 routing library for PHP

README 文档

README

Build Status Scrutinizer Code Quality Code Climate PHP 7 Latest Stable Version License

Slim, fast and full compatible PSR-7 & PSR-15 routing library for PHP.

Why another routing library ?

Installation

Install via the composer utility.

composer require "phoole/route"

or add the following lines to your composer.json

{
    "require": {
       "phoole/route": "1.*"
    }
}

Usage

Inject route definitions (pattern, handler, default values etc.) into the dispatcher and then call either match() or process().

use Phoole\Route\Router;
use GuzzleHttp\Psr7\ServerRequest;
use Psr\Http\Message\ServerRequestInterface;

$router = (new Router())
    ->addGet(
        '/blog/{action:xd}[/{year:d}[/{month:d}[/{date:d}]]]',
        function(ServerRequestInterface $request) {
            $params = $request->getAttribute(Router::URI_PARAMETERS);
            echo "action is " . $params['action'];
        }
    )->addPost(
        '/blog/post',
        'handler2'
    )->addRoute(new Route(
        'GET,HEAD',
        '/blog/read[/{id:d}]',
        'handler3',
        ['id' => '1'] // default values
    ));

// diaptcher (match & execute controller action)
$result = $router->match(new ServerRequest('GET', '/blog/list/2016/05/01'));

if ($result->isMatched()) {
    echo "WOW matched";
}

Or load routes from an array,

$routes = [
    ['GET', '/user/{action:xd}/{id:d}', 'handler1', ['id' => 1]],
    [ ... ],
    ...
];
$router = new Router($routes);

Route syntax

  • {Named} parameters

    A route pattern syntax is used where {foo} specifies a named parameter or a placeholder with name foo and default regex pattern [^/]++. In order to match more specific types, you may specify a custom regex pattern like {foo:[0-9]+}.

    // with 'action' & 'id' two named params
    $dispatcher->addGet('/user/{action:[^0-9/][^/]*}/{id:[0-9]+}', 'handler1');

    Predefined shortcuts can be used for placeholders as follows,

    ':d}'   => ':[0-9]++}',             // digit only
    ':l}'   => ':[a-z]++}',             // lower case
    ':u}'   => ':[A-Z]++}',             // upper case
    ':a}'   => ':[0-9a-zA-Z]++}',       // alphanumeric
    ':c}'   => ':[0-9a-zA-Z+_\-\.]++}', // common chars
    ':nd}'  => ':[^0-9/]++}',           // not digits
    ':xd}'  => ':[^0-9/][^/]*+}',       // no leading digits

    The previous pattern can be rewritten into,

    // with 'action' & 'id' two named params
    $router->addGet('/user/{action:xd}/{id:d}', 'handler1');
  • [Optional] segments

    Optional segments in the route pattern can be specified with [] as follows,

    // $action, $year/$month/$date are all optional
    $pattern = '/blog[/{action:xd}][/{year:d}[/{month:d}[/{date:d}]]]';

    where optional segments can be NESTED. Unlike other libraries, optional segments are not limited to the end of the pattern, as long as it is a valid pattern like the [/{action:xd}] in the example.

  • Syntax limitations

    • Parameter name MUST start with a character

      Since {2} has special meanings in regex. Parameter name MUST start with a character. And the use of {} inside/outside placeholders may cause confusion, thus is not recommended.

    • [] outside placeholder means OPTIONAL segment only

      [] can not be used outside placeholders as part of a regex pattern, IF YOU DO NEED to use them as part of the regex pattern, please include them INSIDE a placeholder.

    • Use of capturing groups () inside placeholders is not allowed

      Capturing groups () can not be used inside placeholders. For example {user:(root|phoole)} is not valid. Instead, you can use either use {user:root|phoole} or {user:(?:root|phoole)}.

  • Default Values

    Default values can be added to named parameters at the end in the form of {action:xd=list}. Default values have to be alphanumeric chars. For example,

    // $action, $year/$month/$date are all optional
    $pattern = '/blog[/{action:xd=list}][/{year:d=2016}[/{month:d=01}[/{date:d=01}]]]';
    $router->addGet($pattern, 'handler');

Routes

  • Same route pattern

    User can define same route pattern with different http methods.

    $router
        ->addGet('/user/{$id}', 'handler1')
        ->addPost('/user/{$id}', 'handler2');

Handlers

  • Handler resolving

    Most of the time, matching route will return a handler like [ 'ControllerName', 'actionName' ]. Handler resolver can be used to resolving this pseudo handler into a real callable.

    Users may write their own handler resolver by implementing Phoole\Route\Resolver\ResolverInterface.

Algorithms

  • FastRoute algorithm

    This Fast Route algorithm is implemented in Phoole\Route\Parser\FastRouteParser class and explained in detail in this article "Fast request routing using regular expressions".

    phoole/route uses this algorithm by default.

  • Comments on routing algorithms

    • It does NOT matter that much as you may think.

      If you are using routing library in your application, different algorithms may differ only 0.1 - 0.2ms for a single request, which seems meaningless for an application unless you are using it as a standalone router.

    • Try network routing or server routing if you just CRAZY ABOUT THE SPEED.

Testing

$ composer test

Dependencies

  • PHP >= 7.2.0

Appendix

  • Routing issues

    Base on the request informations, such as request device, source ip, request method etc., service provider may direct request to different hosts, servers, app modules or handlers.

    • Network level routing

      Common case, such as routing based on request's source ip, routes the request to a NEAREST server, this is common in content distribution network (CDN), and is done at network level.

    • Web server routing

      For performance reason, some of the simple routing can be done at web server level, such as using apache or ngix configs to do simple routing.

      For example, if your server goes down for maintenance, you may replace the .htaccess file as follows,

      DirectorySlash Off
      Options -MultiViews
      DirectoryIndex maintenance.php
      RewriteEngine On
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteCond %{REQUEST_FILENAME} !-l
      RewriteRule ^ maintenance.php [QSA,L]
      
    • App level routing

      It solves much more complicated issues, and much more flexible.

      Usually, routing is done at a single point index.php. All the requests are configured to be handled by this script first and routed to different routines.

phoole/route 适用场景与选型建议

phoole/route 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 18 次下载、GitHub Stars 达 3, 最近一次更新时间为 2019 年 10 月 30 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「route」 「php」 「library」 「middleware」 「psr-7」 「swoole」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

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

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

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: Apache-2.0
  • 更新时间: 2019-10-30