首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PHP Slim-3:如何在内部重定向到另一条路由

PHP Slim-3:如何在内部重定向到另一条路由
EN

Stack Overflow用户
提问于 2019-11-30 07:30:36
回答 3查看 1.7K关注 0票数 1

我有一个通用的路线如下-

代码语言:javascript
运行
复制
$app->map(['GET', 'POST'], "/", function (\Slim\Http\Request $request, \Slim\Http\Response $response) use ($app) {
    // Some random version 1 processing here ...
}

我有一个类似于下面的v2版本-

代码语言:javascript
运行
复制
$app->map(['GET', 'POST'], "/api/v2", function (\Slim\Http\Request $request, \Slim\Http\Response $response) use ($app) {
    // Some random version 2 processing here ...
}

我有个问题要解决-

前端总是访问API的v1 (泛型路由)。我需要根据参数v2 __的值在内部重定向到appversion

如何在不向客户端发出302重定向头的情况下,在瘦框架路由中做到这一点?基本上,我需要在内部重定向到服务器本身。

注意:我知道和重写。让我们把它们放在一边,把范围限制在仅局限于纤细的框架路由上。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-12-02 07:52:22

您想要实现的在技术上是可能的,但在我看来,您的问题背后的原因似乎是您希望引入API的新版本,但是您不想(或者不能)更新前端以调用新版本,而是希望在后端处理这个问题。

如果要根据appversion而不是命中的端点来决定需要调用哪个版本的API,那么定义v1v2端点有什么好处呢?

如果有人调用您的v1端点,他们需要您的v1响应,如果有人需要您的v2响应,则必须调用您的v2端点。如果您为v1v2端点返回相同的响应,那么基本上是在更新您的v1端点行为。

无论如何,您希望在另一个路由回调中分派另一个路由,下面是一个完全工作的示例,演示如何使用subRequest完成该任务

代码语言:javascript
运行
复制
<?php
require 'vendor/autoload.php';

$app = new \Slim\App;

$app->map(['GET', 'POST'], '/v1', function($request, $response) use ($app) {
    // Get the appversion query parameter and make the decision based on its value
    $appVersion = $request->getParam('appversion');
    if($appVersion == '1.0') {
        return $app->subRequest($request->getMethod(), '/v2',
            http_build_query($request->getQueryParams()),
            $request->getHeaders(),
            $request->getCookieParams(),
            $request->getBody()->getContents()
        );
    }
    return 'API version: v1, appversion: ' . $appVersion;
});

$app->map(['GET', 'POST'], '/v2', function($request, $response) {
    return 'API version: v2, request method: ' . $request->getMethod() .', appversion: '. $request->getParam('appversion') . ', body: <pre>' . print_r($request->getParsedBody(), 1);
});

$app->get('/form', function() {
return <<<form
    <form method="POST" action="/v1?appversion=1.0">
        <input type="text" name="foo" value="bar">
        <button type="submit" value="submit">Submit</button>
    </form>
form;
});

$app->run();

现在,如果您试图到达/v1?appversion=1.0,则将返回来自/v2回调的响应。试图使用等于任何其他值(例如,/v1 )的appversion到达appversion,将导致应用程序返回v1响应。

subRequest方法还能够处理POST请求。请参考Slim代码库中的方法文档。该示例提供了一个/form URI来演示这一点。

票数 1
EN

Stack Overflow用户

发布于 2019-11-30 08:58:22

我会在一个路由定义中使用可选段来完成这个任务。

代码语言:javascript
运行
复制
use Psr\Http\Message\{
    ServerRequestInterface as Request,
    ResponseInterface as Response
};

$app->map(['GET', 'POST'], '/[{v2:api/v2}]', function (Request $request, Response $response, array $args) {
    if (isset($args['v2'])) { // You may also check $request->getAttribute('appversion')
        // Version 2 processing here...

        // return $response;
    }

    // Version 1 processing here...

    // return $response;
});
票数 5
EN

Stack Overflow用户

发布于 2019-11-30 07:45:30

您需要抽象调用并创建控制器(也就是说,您的代码不会那么苗条)。

示例:

代码语言:javascript
运行
复制
function doV2() {
    // ... do V2 things
}
function doV1() {
    // ... do V1 things
}

$app->map(['GET', 'POST'], "/", function (\Slim\Http\Request $request, \Slim\Http\Response $response) use ($app) {
    if($app->request()->params('appversion') === 'v2') return doV2();
    doV1();
}
$app->map(['GET', 'POST'], "/api/v2", function (\Slim\Http\Request $request, \Slim\Http\Response $response) use ($app) {
    doV2();
}

您不能在内部“重定向”的原因是您的“控制器”是匿名闭包,因此您无法命名/引用/调用它们。相反,如果将它们抽象成函数(是的,您可能也需要传入$request/$response ),那么您已经为适当的路由指定了方法。

除了定义闭包或函数之外,您还可以定义控制器,并在路由器中使用SlimPHP的容器解决方案--这是一个很好的示例在路由器文档中

最后,您可能需要使用中间件来根据应用程序参数更改所发生的事情,这取决于您想要实现的目标的复杂性。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59114173

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档