HttpKernel组件

编辑本页

警告:您正在浏览的文档欧宝官网下载appob娱乐下载Symfony 5.2,现已不再维护。

本页的更新版本用于Syob娱乐下载mfony 6.2(当前稳定版本)。

HttpKernel组件

HttpKernel组件提供了一个结构化的过程请求成一个响应通过使用EventDispatcher组件。它足够灵活,可以创建全栈框架(Symfony)、微框架(Silex)或高级CMS系统(Drupal)。ob娱乐下载

安装

1
编译器需要symfony/httpob娱乐下载-kernel

请注意

如果在Symfony应用程序外部安装此组件,则必须要求ob娱乐下载供应商/ autoload.php文件,以启用Composer提供的类自动加载机制。读这篇文章欲知详情。

请求的工作流

另请参阅

本文解释了如何在任何PHP应用程序中使用HttpKernel特性作为独立组件。在Syob娱乐下载mfony应用程序中,一切都已经配置好,可以使用了。读了控制器而且事件和事件监听器文章,了解如何使用它在Symfony应用程序中创建控制器和定义事件。ob娱乐下载

每个HTTP网络交互都以请求开始,以响应结束。作为开发人员,您的工作是创建PHP代码来读取请求信息(例如URL),并创建并返回响应(例如HTML页面或JSON字符串)。这是Symfony应用程序中请求工作流的简化概述:ob娱乐下载

  1. 用户要求一个资源在一个浏览器
  2. 浏览器发送一个请求服务器
  3. ob娱乐下载给出了应用程序一个请求对象;
  4. 应用程序生成一个响应对象的数据初始化请求对象;
  5. 服务器返回响应浏览器
  6. 浏览器显示了资源用户

通常,某种框架或系统被构建来处理所有重复的任务(例如路由、安全等),以便开发人员可以构建每一个页面应用程序的。完全如何这些系统的构建差别很大。HttpKernel组件提供了一个接口,该接口形式化了从请求开始并创建适当响应的过程。组件应该是任何应用程序或框架的核心,无论系统的体系结构如何变化:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
名称空间ob娱乐下载组件HttpKernel使用ob娱乐下载组件HttpFoundation请求接口HttpKernelInterface/ /……/ * * *@returnResponse响应实例*/公共函数处理(请求请求, int类型= self::MASTER_REQUEST, bool=真);}

在内部,HttpKernel:处理()的具体实施HttpKernelInterface:处理()-定义一个以请求以a结尾响应

这个工作流的确切细节是理解内核(以及Symfony Framework或任何其他使用内核的库)如何工作的关键。ob娱乐下载

HttpKernel:由事件驱动

HttpKernel:处理()方法通过调度事件在内部工作。这使得方法既灵活,又有点抽象,因为用HttpKernel构建的框架/应用程序的所有“工作”实际上都是在事件侦听器中完成的。

为了帮助解释这个过程,本文档考察了这个过程的每个步骤,并讨论了HttpKernel的一个具体实现——Symfony框架——是如何工作的。ob娱乐下载

最初,使用HttpKernel不需要很多步骤。创建一个事件调度器和一个控制器和参数解析器(下面解释)。为了完成内核的工作,你需要在下面讨论的事件中添加更多的事件监听器:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
使用ob娱乐下载组件EventDispatcherEventDispatcher使用ob娱乐下载组件HttpFoundation请求使用ob娱乐下载组件HttpFoundationRequestStack使用ob娱乐下载组件HttpKernel控制器ArgumentResolver使用ob娱乐下载组件HttpKernel控制器ControllerResolver使用ob娱乐下载组件HttpKernelHttpKernel//创建Request对象请求=请求::createFromGlobals ();调度程序EventDispatcher ();/ /……添加一些事件监听器//创建控制器和参数解析器controllerResolverControllerResolver ();argumentResolverArgumentResolver ();//实例化内核内核HttpKernel (调度程序controllerResolverRequestStack (),argumentResolver);//实际执行内核,将请求转换为响应//通过调度事件,调用控制器,并返回响应响应内核->处理(请求);//发送报头并回显内容响应->send ();//触发内核。终止事件内核->终止(请求响应);

看到“HttpKernel组件“为了更具体的实施。

有关向下面的事件添加侦听器的一般信息,请参见HttpKernel组件

谨慎

从3.1年起HttpKernel的实例,接受第四个参数ArgumentResolverInterface.在4.0中,这个参数将成为强制性的。

另请参阅

有一个关于使用HttpKernel组件和其他Symfony组件来创建您自己的框架的精彩系列教程。ob娱乐下载看到简介

1)kernel.request事件

典型的目的控件中添加更多信息请求,初始化部分系统,或返回响应如果可能(例如,一个拒绝访问的安全层)。

内核事件信息表

在内部分派的第一个事件HttpKernel:处理kernel.request,其中可能有各种不同的侦听器。

这个事件的听众可以是各种各样的。某些侦听器(例如安全侦听器)可能有足够的信息来创建响应立即对象。例如,如果安全侦听器确定某个用户没有访问权限,则该侦听器可能返回RedirectResponse到登录页面或403拒绝访问响应。

如果一个响应在此阶段返回,则流程直接跳转到kernel.response事件。

其他侦听器初始化事物或向请求添加更多信息。对象上确定和设置区域设置请求对象。

另一个常见的侦听器是路由。路由侦听器可以处理请求并确定应该呈现的控制器(请参阅下一节)。事实上,请求对象具有一个"属性包,这是一个完美的地方来存储这些额外的,特定于应用程序的数据请求。这意味着如果您的路由器侦听器以某种方式确定了控制器,它可以将其存储在请求属性(可由控制器解析器使用)。

总的来说,目的kernel.request事件是创建并返回一个响应直接,或添加信息请求(例如设置语言环境或设置一些其他信息请求属性)。

请注意

属性的响应时kernel.request事件时,传播停止。这意味着优先级较低的侦听器将不会被执行。

最重要的听众kernel.request的ob娱乐下载RouterListener.该类执行路由层,该层返回一个数组匹配请求的信息,包括_controller以及路由模式中的任何占位符(例如。{蛞蝓}).看到路由的文档欧宝官网下载app

该信息数组存储在请求对象的属性数组中。在这里添加路由信息还不做任何事情,但将在解析控制器时使用。

2)解析控制器

假设没有kernel.request侦听器能够创建响应在HttpKernel中,下一步是确定和准备(即解析)控制器。控件是最终应用程序代码的一部分,它负责创建和返回响应对于特定的页面。唯一的要求是它是一个PHP可调用的-即一个函数,一个对象上的方法或关闭

如何请求的确切控制器完全取决于您的应用程序。这是“控制器解析器”的工作——一个实现的类ControllerResolverInterface的构造函数参数之一HttpKernel

你的工作是创建一个实现接口的类,并填写它的方法:getController ().事实上,一个默认的实现已经存在,你可以直接使用或从中学习:ControllerResolver.这个实现在下面的侧栏中有更多的解释:

1 2 3 4 5 6 7 8
名称空间ob娱乐下载组件HttpKernel控制器使用ob娱乐下载组件HttpFoundation请求接口ControllerResolverInterface公共函数getController(请求请求;}

在内部,HttpKernel:处理()方法首先调用getController ()在控制器解析器上。此方法被传递请求并负责根据请求的信息确定并返回一个PHP可调用对象(控制器)。

Symfob娱乐下载ony框架使用内置的ControllerResolver类(实际上,它使用了一个带有下面提到的一些额外功能的子类)。类上的信息请求对象的属性财产在RouterListener

getController

ControllerResolver寻找一个_controller按下请求对象的attributes属性(请记住,此信息通常放在请求通过RouterListener).然后这个字符串被转换成一个PHP可调用对象,方法如下:

a)如果_controllerkey不遵循推荐的PHP名称空间
格式(如。控制器应用\ \ DefaultController:索引)它的格式转换成它。例如,遗产FooBundle:默认值:索引格式将更改为Acme \ FooBundle \控制器\ DefaultController: indexAction.这个变换是特定于ControllerResolverSymfony框架使用的子类。ob娱乐下载
b)你的控制器类的一个新实例用no
构造函数参数。
c)控制器实现ContainerAwareInterface
setContainer ()在控制器对象上调用,并将容器传递给它。此步骤也是特定于ControllerResolverSymfony框架使用的子类。ob娱乐下载

3)kernel.controller事件

典型的目的:在控制器执行之前初始化东西或更改控制器。

内核事件信息表

在确定控制器可调用对象之后,HttpKernel:处理()分派kernel.controller事件。此事件的监听器可能初始化系统的某些部分,这些部分需要在确定某些东西(例如控制器、路由信息)后,但在控制器执行之前初始化。有关一些示例,请参阅下面的Symfony部分。ob娱乐下载

此事件的监听器也可以通过调用完全改变可调用的控制器ControllerEvent: setController在此事件上传递给侦听器的事件对象上。

有一些小的听众kernel.controller事件,并且许多处理在启用剖ob娱乐下载析器时收集剖析器数据。

一位有趣的听众来自SensioFrameworkExtraBundle.这个监听器@ParamConverter函数允许你传递一个完整的对象(例如a帖子对象)赋给控制器,而不是标量值(例如id参数)。〇倾听者ParamConverterListener-使用反射来查看控制器的每个参数,并尝试使用不同的方法将它们转换为对象,然后存储在属性的属性请求对象。阅读下一节,了解为什么这很重要。

4)获取控制器参数

接下来,HttpKernel:处理()调用ArgumentResolverInterface: getArguments ().记住,控制器返回getController ()是可调用的。的目的getArguments ()是返回应传递给该控制器的参数数组。具体如何做到这一点完全取决于您的设计,尽管内置ArgumentResolver就是一个很好的例子。

在这一点上,内核有一个PHP可调用对象(控制器)和一个参数数组,当执行该可调用对象时应该传递这些参数。

现在您确切地知道了控制器可调用对象(通常是控制器对象中的一个方法)是什么ArgumentResolver使用反射对象的数组返回的名字每一个论点。然后它遍历这些参数,并使用以下技巧来确定应该为每个参数传递哪个值:

a)如果请求属性包包含一个与名称匹配的键
参数的值,使用该值。例如,如果控制器的第一个参数是美元蛞蝓有一个鼻涕虫输入请求 属性包,该值被使用(通常该值来自RouterListener).
b)如果控制器中的参数是Symfony的类型暗示ob娱乐下载
请求对象,请求作为值传入。
c)如果函数或方法参数为可变请求
属性包包含该参数的数组,它们都可以通过可变论点。

方法的解析器提供了此功能ArgumentValueResolverInterface.有四个实现提供了Symfony的默认行为,但自定义是这里的关键。ob娱乐下载通过实现ArgumentValueResolverInterface你自己,然后把这个交给ArgumentResolver,您可以扩展此功能。

5)调用控制器

下一步HttpKernel:处理()Does正在执行控制器。

控制器的工作是为给定的资源构建响应。这可以是一个HTML页面,一个JSON字符串或其他任何东西。与迄今为止流程的其他部分不同,这一步是由“终端开发人员”为构建的每个页面实现的。

通常,控制器将返回一个响应对象。如果这是真的,那么内核的工作就差不多完成了!在本例中,下一步是kernel.response事件。

但如果控制器返回的不是a响应,那么内核有更多的工作要做-kernel.view(因为最终目标是总是生成响应对象)。

请注意

控制器必须返回某物.如果控制器返回,则会立即抛出异常。

6)kernel.view事件

典型的目的:转换非响应从控制器返回值到响应

内核事件信息表

如果控制器不返回响应对象,然后内核分派另一个事件-kernel.view.此事件的监听器的工作是使用控制器的返回值(例如数据数组或对象)来创建一个对象响应

如果你想使用一个“视图”层:而不是返回一个响应从控制器返回表示页面的数据。此事件的侦听器然后可以使用此数据创建响应这是在正确的格式(如HTML, JSON等)。

在此阶段,如果没有侦听器对事件设置响应,则抛出异常:要么是控制器一个视图监听器必须总是返回响应

请注意

属性的响应时kernel.view事件时,传播停止。这意味着优先级较低的侦听器将不会被执行。

类的默认侦听器在Symfony框架中没有ob娱乐下载kernel.view事件。然而,SensioFrameworkExtraBundle向此事件添加侦听器。如果你的控制器返回一个数组,你把@Template注释,然后这个侦听器呈现一个模板,将您从控制器返回的数组传递给该模板,并创建一个响应包含从该模板返回的内容。

此外,一个流行的社区捆绑包欧宝体育平台怎么样FOSRestBundle在这个事件上实现一个监听器,目的是给你一个健壮的视图层,能够使用单个控制器返回许多不同的内容类型的响应(例如HTML、JSON、XML等)。

7)kernel.response事件

典型的目的:修改响应对象

内核事件信息表

内核的最终目标是转换请求成一个响应.的响应时创建的kernel.request事件返回控制器,或由某个侦听器返回到kernel.view事件。

不管谁创建的响应,另一事件-kernel.response之后会被直接发送。此事件的典型侦听器将修改响应对象的内容,例如修改标头、添加cookie,甚至更改响应本身(例如,在结束之前注入一些JavaScript< /身体>HTML响应的标签)。

在此事件被分派之后,最终的响应对象返回的处理().在最典型的用例中,然后可以调用send ()方法,该方法发送标头并打印响应内容。

在Symfony框架中,这个事件有几个较小的侦听器,大多数侦听器以某种方式修改响应。ob娱乐下载例如,WebDebugToolbarListener的页面底部注入一些JavaScriptdev使web调试工具栏显示的环境。另一个侦听器,ContextListener将当前用户的信息序列化到会话中,以便在下一个请求时可以重新加载它。

8)kernel.terminate事件

典型的目的:在响应流发送给用户后执行一些“重”操作

内核事件信息表

HttpKernel进程的最后一个事件是kernel.terminate并且是唯一的,因为它发生了HttpKernel:处理()方法,并且在将响应发送给用户之后。回想一下上面,然后使用内核的代码,像这样结束:

1 2 3 4 5
//发送报头并回显内容响应->send ();//触发内核。终止事件内核->终止(请求响应);

如你所见,通过打电话内核- >终止发送响应后,您将触发kernel.terminate事件,在此事件中,您可以执行某些可能延迟的操作,以便尽快向客户端返回响应(例如发送电子邮件)。

谨慎

在内部,HttpKernel使用fastcgi_finish_requestPHP函数。这意味着,目前,只有PHP FPM服务器API能够在服务器的PHP进程仍然执行某些任务时向客户端发送响应。对于所有其他服务器api,监听器kernel.terminate仍然执行,但是直到它们全部完成才将响应发送到客户端。

请注意

使用kernel.terminate事件是可选的,并且只应该在内核实现时调用TerminableInterface

如果你使用假脱机内存选项的默认Symfony邮件发送程序,然后ob娱乐下载EmailSenderListener激活,它实际上会发送您在请求期间计划发送的任何电子邮件。

异常处理:kernel.exception事件

典型的目的:处理某种类型的异常并创建适当的响应返回异常

内核事件信息表

如果在内部的任何位置抛出异常HttpKernel:处理(),另一事件-kernel.exception抛出。在内部,身体处理()方法封装在try-catch块中。抛出任何异常时,kernel.exception事件被分派,以便您的系统可以以某种方式响应异常。

向此事件的每个侦听器传递一个ExceptionEvent对象,您可以使用该对象通过getThrowable ()方法。此事件的典型侦听器将检查某种类型的异常并创建适当的错误响应

例如,要生成404页面,您可以抛出一个特殊类型的异常,然后在此事件上添加一个侦听器,该侦听器查找该异常并创建并返回404响应.事实上,HttpKernel组件附带了一个ErrorListener,如果您选择使用它,它将默认执行此操作和更多操作(有关详细信息,请参阅下面的侧栏)。

请注意

属性的响应时kernel.exception事件时,传播停止。这意味着优先级较低的侦听器将不会被执行。

有两个主要的监听器kernel.exception当使用Symfony框架时。ob娱乐下载

HttpKernel组件中的ErrorListener

第一个是HttpKernel组件的核心,并被调用ErrorListener.听众有几个目标:

  1. 抛出的异常被转换为FlattenException对象,其中包含关于请求的所有信息,但可以打印和序列化。
  2. 如果原始异常实现HttpExceptionInterface,然后getStatusCode ()而且getHeaders ()异常时调用,并用于填充FlattenException对象。这个想法是在创建最终响应时的下一步中使用这些。方法设置自定义HTTP标头,可以始终使用setheader ()方法派生的异常textbox类。
  3. 如果原始异常实现RequestExceptionInterface的状态码FlattenException对象使用400并且没有修改其他头文件。
  4. 执行控制器并传递扁平异常。要呈现的确切控制器作为构造函数参数传递给此侦听器。该控制器将返回final响应对于此错误页。

安全组件中的ExceptionListener

另一个重要的监听器是ExceptionListener.此侦听器的目标是处理安全异常,并且在适当时,帮助要进行身份验证的用户(例如重定向到登录页面)。

创建事件监听器

如您所见,您可以创建事件侦听器并将其附加到过程中分派的任何事件HttpKernel:处理()周期。通常监听器是一个带有被执行方法的PHP类,但它可以是任何东西。有关创建和附加事件侦听器的详细信息,请参见EventDispatcher组件

对象上的一个常量定义了每个“内核”事件的名称KernelEvents类。此外,每个事件侦听器都传递一个参数,该参数是类的某个子类KernelEvent.该对象包含关于系统当前状态的信息,每个事件都有自己的事件对象:

的名字 KernelEvents常数 参数传递给侦听器
kernel.request KernelEvents:请求 RequestEvent
kernel.controller KernelEvents:控制器 ControllerEvent
kernel.controller_arguments KernelEvents: CONTROLLER_ARGUMENTS ControllerArgumentsEvent
kernel.view KernelEvents:视图 ViewEvent
kernel.response KernelEvents:响应 ResponseEvent
kernel.finish_request KernelEvents: FINISH_REQUEST FinishRequestEvent
kernel.terminate KernelEvents:终止 TerminateEvent
kernel.exception KernelEvents:异常 ExceptionEvent

一个完整的工作示例

当使用HttpKernel组件时,您可以自由地将任何侦听器附加到核心事件,使用实现HttpKernel的任何控制器解析器ControllerResolverInterface并使用任何参数解析器实现ArgumentResolverInterface.然而,HttpKernel组件自带一些内置监听器和其他可以用来创建一个工作示例的东西:

12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
使用ob娱乐下载组件EventDispatcherEventDispatcher使用ob娱乐下载组件HttpFoundation请求使用ob娱乐下载组件HttpFoundationRequestStack使用ob娱乐下载组件HttpFoundation响应使用ob娱乐下载组件HttpKernel控制器ArgumentResolver使用ob娱乐下载组件HttpKernel控制器ControllerResolver使用ob娱乐下载组件HttpKernelEventListenerRouterListener使用ob娱乐下载组件HttpKernelHttpKernel使用ob娱乐下载组件路由匹配器UrlMatcher使用ob娱乐下载组件路由RequestContext使用ob娱乐下载组件路由路线使用ob娱乐下载组件路由RouteCollection路线RouteCollection ();路线->add (“你好”路线(“/ hello /{名称}”, (“_controller”= >函数(请求请求返回响应(sprintf (“你好,% s”请求->get (“名字”)));}));请求=请求::createFromGlobals ();匹配器UrlMatcher (路线RequestContext ());调度程序EventDispatcher ();调度程序->addSubscriber (RouterListener (匹配器RequestStack ()));controllerResolverControllerResolver ();argumentResolverArgumentResolver ();内核HttpKernel (调度程序controllerResolverRequestStack (),argumentResolver);响应内核->处理(请求);响应->send ();内核->终止(请求响应);

子请求

除了被发送到的main请求之外HttpKernel:处理(),你也可以发送所谓的“分请求”。子请求的外观和行为与其他请求相似,但通常只用于呈现页面的一小部分,而不是整个页面。最常见的是从控制器发出子请求(或者从模板内部发出,由控制器渲染)。

要执行子请求,使用HttpKernel:处理(),但将第二个参数更改如下:

12 3 4 5 6 7 8 9 10 11 12
使用ob娱乐下载组件HttpFoundation请求使用ob娱乐下载组件HttpKernelHttpKernelInterface/ /……//根据需要手动创建一些其他请求请求请求();//例如,可能手动设置它的_controller请求->属性->集(“_controller”'...');响应内核->处理(请求, HttpKernelInterface::SUB_REQUEST);//对这个响应执行一些操作

这创建了另一个完整的请求-响应周期,其中新的请求被转化为响应.内部唯一的区别是一些侦听器(例如安全)可能只对主请求起作用。的某个子类传递给每个侦听器KernelEvent,他的isMasterRequest ()可用于检查当前请求是“主”请求还是“子”请求。

例如,只需要对主请求起作用的侦听器可能是这样的:

1 2 3 4 5 6 7 8 9 10 11
使用ob娱乐下载组件HttpKernel事件RequestEvent/ /……公共函数onKernelRequestRequestEvent (事件如果(!事件->isMasterRequest ()) {返回;}/ /……

定位资源

HttpKernel组件负责Symfony应用程序中使用的包机制。ob娱乐下载包的关键特性是它们允许覆盖应用程序使用的任何资源(配置文件、模板、控制器、翻译文件等)。

这种覆盖机制之所以有效,是因为资源不是通过它们的物理路径而是通过它们的逻辑路径引用的。例如,services . xml文件存储在资源/ config /一个名为FooBundle的包的目录被引用为@FooBundle /资源/配置/ services . xml.当应用程序覆盖该文件时,即使您更改了FooBundle的目录,该逻辑路径也将工作。

HttpKernel组件提供了一个方法locateResource ()可用于将逻辑路径转换为物理路径:

1
路径内核->locateResource (“@FooBundle /资源/配置/ services . xml”);
此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。