如何在 Slim 3 或 nikic/FastRoute 参数中允许点?

How to allow dots in Slim 3 or nikic/FastRoute parameters?

我正在使用 Slim 3,它使用 nikic/FastRoute,但我遇到了这样的端点问题:

$app->get('/count/{url}', function ($request, $response) use ($curl) {
    $controller = new Proximate\Controller\CountUrl($request, $response);
    $controller->setCurl($curl);
    return $controller->execute();
});

我的计划是将 urlencoded URL 传递到 {url} 并将其注入控制器。例如,对于 http://www.example.com,请求将是:

curl \
    --verbose \
    http://localhost:8080/count/http%3A%2F%2Fwww.example.com%2F

但是,此操作失败并返回 404,因此显然不匹配。这也失败了:

curl \
    --verbose \
    http://localhost:8080/count/http%3A%2F%2Fwww.

然而,奇怪的是,这确实匹配(即没有尾随点):

curl \
    --verbose \
    http://localhost:8080/count/http%3A%2F%2Fwww

我最初认为是 urlencoded 斜线混淆了它 (%2F) 但在没有这些字符的情况下尝试过,我发现实际上它是字符串中任意位置的点。为什么这不匹配,我是否需要正则表达式匹配才能使其正常工作?

我正在为这个应用程序使用 PHP 内置网络服务器。

进一步挖掘后,我发现这是由 PHP 内置 Web 服务器引起的,根本不是 Slim 或 FastRoute 的问题。这里是 the Slim bug report and here is one for PHP.

遗憾的是核心 PHP 团队已标记为 Won't fix,因为服务器仅用于测试。就个人而言,我认为关于不将此服务器用于生产的警告有点夸大(我的 Docker 容器保持在合理可管理的大小 因为 我没有把 Apache 扔在那里作为嗯)。

谢天谢地,有一个修复程序 - 在 URL 中指定脚本名称将导致 PHP 将其余部分正确传递给路由系统。像这样:

curl \
    --verbose \
    http://localhost:8080/index.php/count/http%3A%2F%2Fwww.example.com%2F
#                         ^^^^^^^^^
#                         Script name

当然,这不是很优雅,所以我可能会切换到其他解决方案。我还没有尝试过,但 this PHP-only web server 看起来很有希望。