【问题标题】:How does the Symfony/Http-foundation component handles Http request and responseSymfony/Http-foundation 组件如何处理 Http 请求和响应
【发布时间】:2019-10-24 19:29:00
【问题描述】:

我被分配到一个项目,该项目需要包含 Symfony 组件以重新组织其业务逻辑。但是,我在查看 Symfony HTTP 基础文档时感到困惑。希望这里有人能帮我解释一下这个组件如何处理用户的 Http 请求和响应。

基本上,我在项目中所做的是:

  1. 拥有一个 PHP 页面会使用请求的 URL 和方法创建 Request 对象

  2. 使用 ApiRouter 将代码定向到所需的控制器

  3. 在控制器中,它会将 HTTP 请求发送到服务器,并根据请求 URL 将响应转换为 Symfony 响应对象。

位置.php

class GetLocation
{
public function __construct($q)
   {
    $request = Request::create('location?v=full&q=' . 
    urlencode($q), 'GET'); //simulates a request using the url
    $rest_api = new RestApi();  //passing the request to api router
    $rest_api->apiRouter($request);
    }
}

ApiRouter.php

    //location router
       $location_route = new Route(
            '/location',
            ['controller' => 'LocationController']
        );
       $api_routes->add('location_route', $location_route);

    //Init RequestContext object
    $context = new RequestContext();
    //generate the context from user passed $request
    $context->fromRequest($request);

    // Init UrlMatcher object matches the url path with router
    // Find the current route and returns an array of attributes
    $matcher = new UrlMatcher($api_routes, $context);
    try {
        $parameters = $matcher->match($request->getPathInfo());
        extract($parameters, EXTR_SKIP);
        ob_start();

        $response = new Response(ob_get_clean());
    } catch (ResourceNotFoundException $exception) {
        $response = new Response('Not Found', 404);
    } catch (Exception $exception) {
        $response = new Response('An error occurred', 500);
    }

我希望知道的是我对逻辑的理解是否正确?以及Request:createFromGlobal这个方法是什么意思,这个和Request:create(URL)有什么区别

如果我的问题需要更具体,请告诉我。

【问题讨论】:

    标签: php symfony symfony-http-foundation


    【解决方案1】:

    首先你的问题比较简单:

    Request::createFromGlobals() 将基于一些 PHP 全局变量创建请求,例如$_SERVER$_GET$_POST,这意味着它将根据我们“进入”的当前请求创建一个请求,即触发我们应用程序的用户请求。另一方面,Request::create() 将在不应用此上下文的情况下构建“新”请求,这意味着您必须自己传递某些信息,例如路径和 HTTP 方法。

    现在关于您的代码以及它是否可以工作。简短的回答是,可能不是。在 GetLocation 中,您创建一个新请求和一个新路由器,并在控制器内部创建一个路由,然后将其添加到路由器。这意味着除非控制器代码在 GetLocation 之前执行,否则路由在路由器中将不可用,这意味着永远不会调用控制器。

    您可能想查看系列:Create your own PHP Framework 在 symfony 文档中,尤其是从 The HttpFoundation Component 开始的部分。希望这能为您解决问题。

    【讨论】:

    • @dbrunmann 确实感谢您的回答,但似乎我在上一篇文章中将路由器名称错误地输入为 ApiController。对于更新的代码,在我的路由器中,每个路径都映射到一个控制器,并以这种方式定义路由器,它会被定向到所需的控制器,还是我必须添加一些代码才能调用控制器类?
    • 我仍然没有完整的图片,但可能还有一些问题。路由中分配的控制器必须是可调用的(如果控制器实现 __invoke 你应该没问题)。更大的问题是,据我所知,您永远不会执行控制器。而不是ob_start() and then new Response(ob_flush()),我希望您调用匹配器返回的控制器,然后返回响应。您可以查看HttpKernel::handleRaw() 以供参考
    • 我相信你是对的。忽略上面的问题,请问Symfony中的路由组件是否能够隐藏URL中的PHP扩展?
    • 简短回答:是的。您的所有请求都通过网络服务器,例如apache 或 nginx,如果该网络服务器在内部将这些请求路由到您的前端控制器(public/index.php 或在旧项目中 public/app.phpweb/app.php),那么您的 Symfony 应用程序将能够获得最初请求的路径(即浏览器 url) ,无论是/foo 还是/foo.php。然后路由器将读取此路径并将其与路由匹配。类似地,如果您使用 UrlGenerator,它将获取路由的名称,然后创建一个匹配它的 URL/路径,有或没有任何扩展名。
    • 请参阅:symfony.com/doc/current/setup/…,以确保您的网络服务器将请求路由到您的应用程序,而不是在键入 http://example.com/foo 时实际查找文件/文件夹。
    猜你喜欢
    • 2011-02-23
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多