HttpKernel组件

编辑该页面

警告:你浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 5.3,不再维护。

这个页面的更新版本Symf欧宝娱乐app下载地址ony 6.2(当前的稳定版本)。

HttpKernel组件

HttpKernel组件转换提供了一个结构化的过程请求成一个响应利用EventDispatcher组件。它是足够灵活来创建一个完整的框架(Symfony),一个micro-framework(石英玻璃)或一个先进的欧宝娱乐app下载地址CMS系统(Drupal)。

安装

1
美元作曲家需要symfony / ht欧宝娱乐app下载地址tp-kernel

请注意

如果你安装这个组件之外的Symfony应用程序,你必须要求欧宝娱乐app下载地址供应商/ autoload.php文件在你的代码,使作曲家提供的类加载机制。读这篇文章为更多的细节。

请求的工作流程

另请参阅

这篇文章解释了如何使用HttpKernel功能作为一个独立的组件在任何PHP应用程序。在Sy欧宝娱乐app下载地址mfony应用程序都已经配置好了,可以使用了。读了控制器事件和事件监听器文章来了解如何使用它来创建控制器和在Symfony应用程序中定义事件。欧宝娱乐app下载地址

每个HTTP web交互始于一个请求并以响应。你的工作作为一个开发人员创建PHP代码读取请求信息(如URL)和创建并返回一个响应(例如,一个HTML页面或JSON字符串)。这是一个简化的概述在Symfony请求工作流应用程序:欧宝娱乐app下载地址

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

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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
名称空间欧宝娱乐app下载地址\组件\HttpKernel;使用欧宝娱乐app下载地址\组件\HttpFoundation\请求;接口HttpKernelInterface{/ /……/ * * *@return响应响应实例* /公共函数处理(请求美元请求,int美元类型= self:: MAIN_REQUEST,保龄球美元= true);}

在内部,HttpKernel:处理()的具体实现HttpKernelInterface:处理()——定义了一个工作流,从一开始请求和结束响应

这个工作流是关键的细节了解内核(和Symfony框架或其他库,使用内核)。欧宝娱乐app下载地址

HttpKernel:由事件驱动的

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

有助于解释这一过程,本文着眼于每个步骤的流程和谈判关于一个特定的实现HttpKernel - Symfony框架的工作原理。欧宝娱乐app下载地址

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

1 2 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
使用欧宝娱乐app下载地址\组件\EventDispatcher\EventDispatcher;使用欧宝娱乐app下载地址\组件\HttpFoundation\请求;使用欧宝娱乐app下载地址\组件\HttpFoundation\RequestStack;使用欧宝娱乐app下载地址\组件\HttpKernel\控制器\ArgumentResolver;使用欧宝娱乐app下载地址\组件\HttpKernel\控制器\ControllerResolver;使用欧宝娱乐app下载地址\组件\HttpKernel\HttpKernel;/ /创建请求对象美元请求=请求::createFromGlobals ();美元调度程序=EventDispatcher ();/ /……添加一些事件监听器/ /创建控制器和参数解析器美元controllerResolver=ControllerResolver ();美元argumentResolver=ArgumentResolver ();/ /实例化内核美元内核=HttpKernel (美元调度程序,美元controllerResolver,RequestStack (),美元argumentResolver);/ /实际执行内核,将请求转化为一个响应/ /通过调度事件,调用控制器,并返回响应美元响应=美元内核- >处理(美元请求);/ /发送内容标题和回声美元响应- >send ();/ /触发内核。终止事件美元内核- >终止(美元请求,美元响应);

看到“HttpKernel组件“对于一个更具体的实现。

对于一般信息将侦听器添加到下面的事件,看到的HttpKernel组件

谨慎

在3.1HttpKernel接受第四个参数,必须的一个实例ArgumentResolverInterface。在4.0这一观点将成为强制性的。

另请参阅

有一个很棒的教程系列使用HttpKernel组件和其他Symfony组件来创建您自己的框架。欧宝娱乐app下载地址看到介绍

1)kernel.request事件

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

内核事件信息表

第一个事件派遣HttpKernel:处理kernel.request,这可能有各种不同的听众。

这个事件的侦听器可能千差万别。一些听众,如安全侦听器,可能有足够的信息来创建一个响应立即对象。例如,如果一个安全侦听器确定用户没有访问,侦听器可能返回RedirectResponse登录页面或403拒绝访问响应。

如果一个响应返回在此阶段,这个过程直接跳过吗kernel.response事件。

其他听众初始化或添加到请求更多信息。例如,一个侦听器可能确定和设置语言环境请求对象。

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

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

请注意

当设置的响应kernel.request事件,停止传播。这意味着较低的听众优先不会被执行。

最重要的侦听器kernel.request在Symfon欧宝娱乐app下载地址y框架RouterListener。这类执行路由层,它返回一个数组关于匹配请求的信息,包括_controller和任何占位符路线的模式(如。{蛞蝓})。看到路由的文档欧宝体育电话

这个数组的信息存储请求对象的属性数组中。添加路由信息还不做任何事,但下当解决控制器使用。

2)解决控制器

假设没有kernel.request侦听器可以创建一个响应HttpKernel,下一步是确定和准备(即解决)控制器。控制器是end-application代码的一部分,负责创建和返回响应为一个特定的页面。唯一的要求是,它是一个PHP调用——也就是一个函数,一个对象或一个方法关闭

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

你的工作是创建一个类实现接口和填写方法:getController ()。事实上,一个默认的实现已经存在,您可以直接使用或学习:ControllerResolver。这个实现是在下面的栏中详细解释:

1 2 3 4 5 6 7 8
名称空间欧宝娱乐app下载地址\组件\HttpKernel\控制器;使用欧宝娱乐app下载地址\组件\HttpFoundation\请求;接口ControllerResolverInterface{公共函数getController(请求美元请求);}

在内部,HttpKernel:处理()方法首先调用getController ()在控制器解析器。该方法通过了请求和负责确定并返回一个PHP调用(控制器)基于请求的信息。

Symf欧宝娱乐app下载地址ony框架使用内置的ControllerResolver类(实际上,它使用一个子类与一些额外的功能下面提到)。这类放置在利用信息请求对象的属性地产在RouterListener

getController

ControllerResolver寻找一个_controller关键在请求对象的属性属性(回想一下,这些信息通常放在请求通过RouterListener)。然后这个字符串转换成一个PHP调用通过以下几点:

)如果_controller关键不遵循推荐PHP名称空间
格式(如。控制器应用\ \ DefaultController:索引)的格式转换成它。例如,遗产FooBundle:默认值:索引格式将改变Acme \ FooBundle \控制器\ DefaultController: indexAction。这种转变是特定的ControllerResolver子类使用Symfony框架。欧宝娱乐app下载地址
b)控制器的一个新实例类被实例化无
构造函数参数。
如果控制器实现ContainerAwareInterface,
setContainer ()是呼吁控制器对象并传递给它的容器。这一步也是具体的ControllerResolver子类使用Symfony框架。欧宝娱乐app下载地址

3)kernel.controller事件

典型的目的:初始化或改变控制器控制器执行之前。

内核事件信息表

控制器可调用后确定,HttpKernel:处理()分派kernel.controller事件。听众这一事件可能会初始化系统的一部分,需要初始化后某些事情已经确定(如控制器,路由信息),但控制器之前执行。一些示例,请参阅下面的Symfony部分。欧宝娱乐app下载地址

听众这个事件也可以改变控制器调用完全通过调用ControllerEvent: setController事件对象,对这一事件的传递给听众。

有一些小的听众kernel.controller事件在Symfony框架,欧宝娱乐app下载地址许多处理收集分析器数据分析器时启用。

来自于一个有趣的侦听器SensioFrameworkExtraBundle。这个监听器@ParamConverter功能允许您通过一个完整的对象(例如帖子对象)控制器,而不是一个标量值(例如一个id参数是你的路线)。侦听器,ParamConverterListener——使用反射来看看每个控制器的参数,并试图用不同的方法将这些对象,然后存储在属性财产的请求对象。阅读下一节看到为什么这很重要。

4)获得控制器参数

接下来,HttpKernel:处理()调用ArgumentResolverInterface: getArguments ()。记住,控制器中返回getController ()是一个可调用的。的目的getArguments ()是返回数组的参数应该传递给控制器。如何这样做是完全取决于你的设计,虽然内置的ArgumentResolver是一个很好的例子。

此时内核有一个PHP调用(控制器)和数组参数,应该通过在执行,可调用的。

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

)如果请求属性包包含一个键相匹配的名称
参数的使用价值。例如,如果第一个参数控制器美元蛞蝓有一个鼻涕虫的关键请求 属性袋,使用价值(通常来自于这个值RouterListener)。
b)如果控制器type-hinted Symfony的论点欧宝娱乐app下载地址
请求对象,请求传入的值。
c)如果函数或方法参数可变请求
属性包包含的参数是一个数组,它们都将可以通过可变论点。

这个功能是由解析器实现ArgumentValueResolverInterface。有四个实现提供的默认行为Symfony但定制是这里的关键。欧宝娱乐app下载地址通过实现ArgumentValueResolverInterface自己和传递的ArgumentResolver,您可以扩展此功能。

5)调用控制器

下一步的HttpKernel:处理()是执行控制器。

控制器的工作是构建响应给定的资源。这可能是一个HTML页面,一个JSON字符串或其他。与其他过程的一部分,到目前为止,这一步是由“用户”,实现每个页面。

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

但是如果除了控制器返回任何东西响应,那么内核有一点工作要做kernel.view(因为最终的目标总是生成一个响应对象)。

请注意

一个控制器必须返回的东西。如果一个控制器返回,立即将抛出一个异常。

6)kernel.view事件

典型的目的:变换一个非-响应从控制器到一个返回值响应

内核事件信息表

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

这可能是有用的,如果你想使用一个“视图”层:而不是返回响应从控制器,你返回的数据代表了页面。一个侦听器,这个事件就可以使用这些数据来创建一个响应以正确的格式(e。g HTML、JSON、等等)。

在这个阶段,如果没有响应的事件侦听器集,然后抛出异常:要么控制器的一个监听器必须始终返回一个视图响应

请注意

当设置的响应kernel.view事件,停止传播。这意味着较低的听众优先不会被执行。

没有默认侦听器在Symfony框架欧宝娱乐app下载地址kernel.view事件。然而,SensioFrameworkExtraBundle一个侦听器添加到这个事件。如果你的控制器返回一个数组,而你的地方@Template注释上面控制器,然后该侦听器显示一个模板,将你从控制器返回的数组传递给模板,并创建一个响应从模板中包含返回的内容。

此外,一个受欢迎的社区包欧宝下载链接FOSRestBundle旨在实现一个侦听器在这个事件给你一个健壮的视图层能够使用一个控制器返回许多不同内容类型的反应(如HTML、JSON、XML等)。

7)kernel.response事件

典型的目的:修改响应对象就在它发送

内核事件信息表

内核是变换的最终目标请求成一个响应。的响应可能是在创建的kernel.request事件,返回的控制器,或者返回一个侦听器kernel.view事件。

不管谁创造了响应另一个事件,kernel.response之后直接派遣。一个典型的这个事件侦听器将修改响应对象在某些方面,比如修改标题,添加饼干,甚至改变的内容响应本身(如注射一些JavaScript结束前< /身体>标签的HTML响应)。

这个事件派遣后,决赛响应对象是回来处理()。在最典型的用例,您可以调用send ()方法,该方法把标题和打印响应内容。

有几个小听众对这个事件在Symfony框架,和大多数修改响应。欧宝娱乐app下载地址例如,WebDebugToolbarListener注入一些JavaScript在页面的底部dev环境导致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

处理异常:kernel.exception事件

典型的目的:处理某种类型的异常和创建一个合适的响应返回的异常

内核事件信息表

任何时候如果抛出一个异常HttpKernel:处理()另一个事件,kernel.exception抛出。在内部,身体的处理()方法是包装在一个try - catch块。任何异常时,kernel.exception事件分派,这样您的系统能应对异常。

这个事件是通过每个侦听器ExceptionEvent对象,您可以使用它来访问原始异常通过getThrowable ()方法。一个典型的这个事件侦听器将检查一个特定类型的异常并创建一个适当的错误响应

例如,生成一个404页的,你可能会抛出一个特殊类型的异常,然后添加一个侦听器在这个事件,寻找这个异常并创建并返回一个404响应。事实上,HttpKernel组件提供了一个ErrorListener如果选择使用,默认将做到这一点,更多的更多细节(请参阅侧栏下面)。

请注意

当设置的响应kernel.exception事件,停止传播。这意味着较低的听众优先不会被执行。

有两个主要的听众kernel.exception当使用Symfony框架。欧宝娱乐app下载地址

ErrorListener HttpKernel组件

第一个核心HttpKernel组件,叫做ErrorListener。侦听器有几个目标:

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

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组件,你可以附加任何侦听器的核心事件,使用任何控制器解析器实现ControllerResolverInterface和使用任何参数解析器实现ArgumentResolverInterface。然而,HttpKernel组件提供了一些内置的听众和一切可以用来创建一个工作示例:

1 2 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 30 31 32 33 34 35 36 37 38
使用欧宝娱乐app下载地址\组件\EventDispatcher\EventDispatcher;使用欧宝娱乐app下载地址\组件\HttpFoundation\请求;使用欧宝娱乐app下载地址\组件\HttpFoundation\RequestStack;使用欧宝娱乐app下载地址\组件\HttpFoundation\响应;使用欧宝娱乐app下载地址\组件\HttpKernel\控制器\ArgumentResolver;使用欧宝娱乐app下载地址\组件\HttpKernel\控制器\ControllerResolver;使用欧宝娱乐app下载地址\组件\HttpKernel\EventListener\RouterListener;使用欧宝娱乐app下载地址\组件\HttpKernel\HttpKernel;使用欧宝娱乐app下载地址\组件\路由\匹配器\UrlMatcher;使用欧宝娱乐app下载地址\组件\路由\RequestContext;使用欧宝娱乐app下载地址\组件\路由\路线;使用欧宝娱乐app下载地址\组件\路由\RouteCollection;美元路线=RouteCollection ();美元路线- >add (“你好”,路线(“/ hello /{名称}”,(“_controller”= >函数(请求美元请求){返回响应(sprintf (“你好,% s”,美元请求- >get (“名字”)));}));美元请求=请求::createFromGlobals ();美元匹配器=UrlMatcher (美元路线,RequestContext ());美元调度程序=EventDispatcher ();美元调度程序- >addSubscriber (RouterListener (美元匹配器,RequestStack ()));美元controllerResolver=ControllerResolver ();美元argumentResolver=ArgumentResolver ();美元内核=HttpKernel (美元调度程序,美元controllerResolver,RequestStack (),美元argumentResolver);美元响应=美元内核- >处理(美元请求);美元响应- >send ();美元内核- >终止(美元请求,美元响应);

子请求

除了“主要”请求发送到HttpKernel:处理(),你也可以发送一个所谓的“子请求”。子请求看起来,就像任何其他的请求,但通常是呈现一个页面的一小部分,而不是一个完整的页面。你最常使子请求,从你的控制器(或者从一个模板中,呈现在你的控制器)。

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

1 2 3 4 5 6 7 8 9 10 11 12
使用欧宝娱乐app下载地址\组件\HttpFoundation\请求;使用欧宝娱乐app下载地址\组件\HttpKernel\HttpKernelInterface;/ /……/ /根据需要手动创建其他请求美元请求=请求();/ /例如,手动设置其_controller美元请求- >属性- >集(“_controller”,“……”);美元响应=美元内核- >处理(美元请求,HttpKernelInterface::SUB_REQUEST);/ /做一些回应

这将创建一个完整的请求-响应周期,这个新的请求转换为响应。内部唯一的区别是,一些听众(如安全性)可能只行动的主要要求。每个侦听器传递的一些子类KernelEvent,他的isMainRequest ()方法可用于检查当前请求是否“主要”或“子”的要求。

例如,一个侦听器,只需要行动的主要请求可能看起来像这样:

1 2 3 4 5 6 7 8 9 10 11
使用欧宝娱乐app下载地址\组件\HttpKernel\事件\RequestEvent;/ /……公共函数onKernelRequestRequestEvent (美元事件){如果(!美元事件- >isMainRequest ()) {返回;}/ /……}

定位资源

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

这最重要的机制,因为资源引用而不是它们的物理路径的逻辑路径。例如,services . xml文件存储在资源/ config /一捆的目录称为FooBundle引用@FooBundle /资源/配置/ services . xml。这个逻辑路径将工作当应用程序覆盖该文件,甚至如果你改变FooBundle的目录。

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

1
美元路径=美元内核- >locateResource (“@FooBundle /资源/配置/ services . xml”);
这项工作,包括代码示例,许可下Creative Commons冲锋队3.0许可证。
欧宝娱乐app下载地址Symfony 5.3支持通过JoliCode