sergiosgc/rest-router

基于文件系统的请求路由器,适用于了解HTTP动词的应用程序(RESTful)

dev-master 2023-04-11 15:35 UTC

This package is auto-updated.

Last update: 2024-09-11 18:51:09 UTC


README

基于文件系统的请求路由器,适用于了解HTTP动词的应用程序(RESTful)

目标

通常PHP请求路由模式是从请求URI中获取脚本文件名,可能是在添加 index.php 后。此路由器遵循相同的逻辑,并在RESTful路径上向上一步。它使用请求HTTP动词(GETPOSTPUT、...)来确定将处理请求的文件系统路径中的正确脚本。

假设一个应用程序存储在文档根目录 /srv/www/myapp 下的应用程序接收三个请求

  1. A GET to /customer/
  2. A POST to /customer/
  3. A PUT to /customer/10

在典型的PHP路由中,前两个请求将由 /srv/www/myapp/customer/index.php 处理,而第三个请求将需要在Web服务器层进行请求重写

使用此路由器,请求将由

  1. /srv/www/myapp/customer/get.php
  2. /srv/www/myapp/customer/post.php
  3. /srv/www/myapp/customer/put.php(提取客户ID是可能的,并在本readme中介绍)

这简化了RESTful应用程序的开发,同时利用应用程序目录结构来映射URL空间。

安装

最简单的方法是使用Composer安装和使用。在你的composer.json中

# composer.json
{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/sergiosgc/composer-fs-rest-router.git"
        }
    ],
    "require": {
        "sergiosgc/rest-router": "dev-master"
    }
}

然后发出 composer updatecomposer install

现在,在您的文档根目录中,创建一个名为index.php的捕获所有脚本

<?php
require_once('vendor/autoload.php');
(new \sergiosgc\router\Rest())->route();

并配置您的Web服务器将所有vhost请求路由到此index.php。例如,在nginx中,vhost文件可能如下所示

server {
  listen 80;

  root /srv/www/myapp;
  index /index.php;

  location / {
    try_files $uri /index.php?$args;
  }

  location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    include fastcgi_params;
  }
}

基本用法

只需为您的RESTful对象创建目录。例如,要处理对 /customer/ 的请求,创建一个目录 /srv/www/myapp/customer/。然后,为要处理的每个方法创建一个脚本文件

  • post.php 用于POST方法(创建)
  • get.php 用于GET/HEAD方法(读取)
  • head.php 用于HEAD方法
  • put.php 用于PUT方法(更新)
  • delete.php 用于DELETE方法(删除)

如果 head.php 不存在,路由器将回退到 get.php。任何方法都接受;文件名应该是小写的动词名称,后面跟 .php

从URL中提取参数

路由器将设置以下两个变量

  • $_SERVER['ROUTER_PATHBOUND_REQUEST_URI']:匹配文件系统目录的URL部分
  • $_SERVER['ROUTER_PATHBOUND_SCRIPT_FILENAME']:从 $_SERVER['ROUTER_PATHBOUND_REQUEST_URI'] 获得的脚本文件名

$_SERVER['ROUTER_PATHBOUND_REQUEST_URI'] 是从 $_SERVER['REQUEST_URI'] 中消耗掉匹配路径中找到的正则表达式文件的成功匹配的结果。它匹配文档根目录中存在的目录。

当使用美化后的URL时,您可以从请求URL的无绑定部分提取额外数据。在上面的示例中,由 /srv/www/myapp/customer/put.php 处理的PUT到 /customer/10 将使 10 成为 $_SERVER['ROUTER_UNBOUND_REQUEST_URI'] 的值。

对于更复杂的URL,您可以使用正则表达式来提取参数。在与动词处理PHP脚本相同的目录中,放下一个带有命名组的正则表达式。让我们假设URL /customer/10/20 被解释为从minid 10到maxid 20的客户。在 /srv/www/myapp/customer/get.php 旁边创建 /srv/www/myapp/customer/get.regex,内容如下

_^(?<minid>[0-9]+)/(?<maxid>[0-9]+)_

请求路由器将使用此正则表达式来

  1. 匹配无绑定请求URI并提取参数minid和maxid。这些将填充 $_REQUEST
  2. 验证无绑定URI是否有效(否则抛出404错误)

URL子树

如果您希望脚本自动处理该URL树节点及其下所有请求,可以使用消耗剩余URI的正则表达式来实现。

例如,一个脚本 /srv/www/myapp/customer/order/get.php 可以处理 /customer/order//customer/order/return/ 这样的URL。要实现这一点,可以在 /srv/www/myapp/customer/order/get.regex 中放置一个正则表达式,如下所示:

_^(?<remaining>.*)$_

路径中最具体的脚本将被使用。例如,如果存在这两个脚本:/srv/www/myapp/customer/order/get.php/srv/www/myapp/customer/get.php,那么URL /customer/order/return/ 将由 /srv/www/myapp/customer/order/get.php 处理。

HTML动词限制的解决方案

虽然HTTP定义了一组丰富的方法,但HTML实际上只允许GET和POST。为了解决这个问题,在HTML中,您可以在任何请求中使用x-verb参数来覆盖HTTP动词。例如,当点击链接 /customer/12?x-verb=DELETE 时,在浏览器中会发出一个GET HTTP请求,但路由器会将其处理为DELETE请求。

调试

通过启用$debug静态变量,您可以获取路由器对URL匹配的调试信息,而不是正常的响应。这可以在上述提到的catch-all脚本中轻松实现,如下所示:

<?php
require_once('vendor/autoload.php');
\sergiosgc\router\Rest::$debug = true;
(new \sergiosgc\router\Rest())->route();