HttpKernel组件
编辑本页警告:您正在浏览的文档欧宝官网下载appob娱乐下载Symfony 2.7,现已不再维护。
读本页的更新版本用于Syob娱乐下载mfony 6.2(当前稳定版本)。
HttpKernel组件
HttpKernel组件提供了一个结构化的过程
请求
成一个响应
通过使用EventDispatcher组件。它足够灵活,可以创建全栈框架(Symfony)、微框架(Silex)或高级CMS系统(Drupal)。ob娱乐下载
安装
1
$编译器需要symfony/httpob娱乐下载-kernel
或者,您可以克隆https://github.com/ob娱乐下载symfony/http-kernel存储库。
请注意
如果在Symfony应用程序外部安装此组件,则必须要求ob娱乐下载供应商/ autoload.php
文件,以启用Composer提供的类自动加载机制。读这篇文章欲知详情。
请求的工作流
每个HTTP网络交互都以请求开始,以响应结束。作为开发人员,您的工作是创建PHP代码来读取请求信息(例如URL),并创建并返回响应(例如HTML页面或JSON字符串)。这是Symfony应用程序中请求工作流的简化概述:ob娱乐下载
- 的用户要求一个资源在一个浏览器;
- 的浏览器发送一个请求到服务器;
- ob娱乐下载给出了应用程序一个请求对象;
- 的应用程序生成一个响应对象的数据初始化请求对象;
- 的服务器返回响应到浏览器;
- 的浏览器显示了资源到用户.
通常,构建某种框架或系统来处理所有重复的任务(例如路由、安全等),以便开发人员可以轻松地构建每个任务页面应用程序的。完全如何这些系统的构建差别很大。HttpKernel组件提供了一个接口,该接口形式化了从请求开始并创建适当响应的过程。组件应该是任何应用程序或框架的核心,无论系统的体系结构如何变化:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
名称空间ob娱乐下载\组件\HttpKernel;使用ob娱乐下载\组件\HttpFoundation\请求;接口HttpKernelInterface{/ /……/ * * *@returnResponse响应实例*/公共函数处理(请求$请求,$类型= self:: MASTER_REQUEST,$抓=真);}
在内部,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
使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpKernel\HttpKernel;使用ob娱乐下载\组件\EventDispatcher\EventDispatcher;使用ob娱乐下载\组件\HttpKernel\控制器\ControllerResolver;//创建Request对象$请求=请求::createFromGlobals ();$调度程序=新EventDispatcher ();/ /……添加一些事件监听器//创建控制器解析器$解析器=新ControllerResolver ();//实例化内核$内核=新HttpKernel ($调度程序,$解析器);//实际执行内核,将请求转换为响应//通过调度事件,调用控制器,并返回响应$响应=$内核->处理($请求);//发送报头并回显内容$响应->send ();//触发内核。终止事件$内核->终止($请求,$响应);
看到“HttpKernel组件“为了更具体的实施。
有关向下面的事件添加侦听器的一般信息,请参见HttpKernel组件.
另请参阅
有一个关于使用HttpKernel组件和其他Symfony组件来创建您自己的框架的精彩系列教程。ob娱乐下载看到简介.
1)kernel.request
事件
典型的目的控件中添加更多信息请求
,初始化部分系统,或返回响应
如果可能(例如,一个拒绝访问的安全层)。
在内部分派的第一个事件HttpKernel:处理是kernel.request
,其中可能有各种不同的侦听器。
这个事件的听众可以是各种各样的。某些侦听器(例如安全侦听器)可能有足够的信息来创建响应
立即对象。例如,如果安全侦听器确定某个用户没有访问权限,则该侦听器可能返回RedirectResponse到登录页面或403拒绝访问响应。
如果一个响应
在此阶段返回,则流程直接跳转到kernel.response事件。
其他侦听器只是初始化事物或向请求添加更多信息。对象上确定和设置区域设置请求
对象。
另一个常见的侦听器是路由。路由侦听器可以处理请求
并确定应该呈现的控制器(请参阅下一节)。事实上,请求
对象具有一个"属性包,这是一个完美的地方来存储这些额外的,特定于应用程序的数据请求。这意味着如果您的路由器侦听器以某种方式确定了控制器,它可以将其存储在请求
属性(可由控制器解析器使用)。
总的来说,目的kernel.request
事件是创建并返回一个响应
直接,或添加信息请求
(例如设置语言环境或设置一些其他信息请求
属性)。
请注意
属性的响应时kernel.request
事件时,传播停止。这意味着优先级较低的侦听器将不会被执行。
kernel.request
在Symfonob娱乐下载y框架中
最重要的听众kernel.request
的ob娱乐下载RouterListener.该类执行路由层,该层返回一个数组匹配请求的信息,包括_controller
以及路由模式中的任何占位符(例如。{蛞蝓}
).看到路由组件.
该信息数组存储在请求对象的属性
数组中。在这里添加路由信息还不做任何事情,但将在解析控制器时使用。
2)解析控制器
假设没有kernel.request
侦听器能够创建响应
在HttpKernel中,下一步是确定和准备(即解析)控制器。控件是最终应用程序代码的一部分,它负责创建和返回响应
对于特定的页面。唯一的要求是它是一个PHP可调用的-即一个函数,一个对象上的方法,或一个关闭
.
但如何请求的确切控制器完全取决于您的应用程序。这是“控制器解析器”的工作——一个实现的类ControllerResolverInterface的构造函数参数之一HttpKernel
.
你的工作是创建一个实现接口的类,并填写它的两个方法:getController ()
而且getArguments ()
.事实上,一个默认的实现已经存在,你可以直接使用或从中学习:ControllerResolver.这个实现在下面的侧栏中有更多的解释:
1 2 3 4 5 6 7 8 9 10
名称空间ob娱乐下载\组件\HttpKernel\控制器;使用ob娱乐下载\组件\HttpFoundation\请求;接口ControllerResolverInterface{公共函数getController(请求$请求);公共函数getArguments(请求$请求,$控制器);}
在内部,HttpKernel:处理()
方法首先调用getController ()在控制器解析器上。此方法被传递请求
并负责根据请求的信息确定并返回一个PHP可调用对象(控制器)。
第二种方法,getArguments (),将被称为另一个事件后-kernel.controller
-被分派。
在Symfony框架中解析控制器ob娱乐下载
Symfob娱乐下载ony框架使用内置的ControllerResolver类(实际上,它使用了一个带有下面提到的一些额外功能的子类)。类上的信息请求
对象的属性
财产在RouterListener
.
getController
的ControllerResolver
寻找一个_controller
按下请求
对象的attributes属性(请记住,此信息通常放在请求
通过RouterListener
).然后这个字符串被转换成一个PHP可调用对象,方法如下:
-
一个)
AcmeDemoBundle:默认值:索引
的格式_controller
关键 -
被更改为另一个字符串,该字符串包含控制器的完整类名和方法名,遵循Symfony中使用的约定。ob娱乐下载
Acme \ DemoBundle \控制器\ DefaultController: indexAction
.这个变换是特定于ControllerResolverSymfony框架使用的子类。ob娱乐下载 - b)你的控制器类的一个新实例用no
- 构造函数参数。
- c)控制器实现ContainerAwareInterface,
-
setContainer ()
在控制器对象上调用,并将容器传递给它。此步骤也是特定于ControllerResolverSymfony框架使用的子类。ob娱乐下载
3)kernel.controller
事件
典型的目的:在控制器执行之前初始化东西或更改控制器。
在确定控制器可调用对象之后,HttpKernel:处理()
分派kernel.controller
事件。此事件的监听器可能初始化系统的某些部分,这些部分需要在确定某些东西(例如控制器、路由信息)后,但在控制器执行之前初始化。有关一些示例,请参阅下面的Symfony部分。ob娱乐下载
此事件的监听器也可以通过调用完全改变可调用的控制器FilterControllerEvent: setController在此事件上传递给侦听器的事件对象上。
kernel.controller
在Symfonob娱乐下载y框架中
有一些小的听众kernel.controller
事件,并且许多处理在启用剖ob娱乐下载析器时收集剖析器数据。
一位有趣的听众来自SensioFrameworkExtraBundle,它与Symfony标准版一起打包。ob娱乐下载这个监听器@ParamConverter函数允许你传递一个完整的对象(例如a帖子
对象)赋给控制器,而不是标量值(例如id
参数)。〇倾听者ParamConverterListener
-使用反射来查看控制器的每个参数,并尝试使用不同的方法将它们转换为对象,然后存储在属性
的属性请求
对象。阅读下一节,了解为什么这很重要。
4)获取控制器参数
接下来,HttpKernel:处理()
调用getArguments ().记住,控制器返回getController ()
是可调用的。的目的getArguments ()
是返回应传递给该控制器的参数数组。具体如何做到这一点完全取决于您的设计,尽管内置ControllerResolver就是一个很好的例子。
在这一点上,内核有一个PHP可调用对象(控制器)和一个参数数组,当执行该可调用对象时应该传递这些参数。
5)调用控制器
下一步很简单!HttpKernel:处理()
执行控制器。
控制器的工作是为给定的资源构建响应。这可以是一个HTML页面,一个JSON字符串或其他任何东西。与迄今为止流程的其他部分不同,这一步是由“终端开发人员”为构建的每个页面实现的。
通常,控制器将返回一个响应
对象。如果这是真的,那么内核的工作就差不多完成了!在本例中,下一步是kernel.response事件。
但如果控制器返回的不是a响应
,那么内核有更多的工作要做-kernel.view(因为最终目标是总是生成响应
对象)。
请注意
控制器必须返回某物.如果控制器返回零
,则会立即抛出异常。
6)kernel.view
事件
典型的目的:转换非响应
从控制器返回值到响应
如果控制器不返回响应
对象,然后内核分派另一个事件-kernel.view
.此事件的监听器的工作是使用控制器的返回值(例如数据数组或对象)来创建一个对象响应
.
如果你想使用一个“视图”层:而不是返回一个响应
从控制器返回表示页面的数据。此事件的侦听器然后可以使用此数据创建响应
这是在正确的格式(如HTML, JSON等)。
在此阶段,如果没有侦听器对事件设置响应,则抛出异常:要么是控制器或一个视图监听器必须总是返回响应
.
请注意
属性的响应时kernel.view
事件时,传播停止。这意味着优先级较低的侦听器将不会被执行。
kernel.view
在Symfonob娱乐下载y框架中
类的默认侦听器在Symfony框架中没有ob娱乐下载kernel.view
事件。然而,有一个核心bundle -SensioFrameworkExtraBundle-做向此事件添加侦听器。如果你的控制器返回一个数组,你把@Template注释,然后这个侦听器呈现一个模板,将您从控制器返回的数组传递给该模板,并创建一个响应
包含从该模板返回的内容。
此外,一个流行的社区捆绑包欧宝体育平台怎么样FOSRestBundle在这个事件上实现一个监听器,目的是给你一个健壮的视图层,能够使用单个控制器返回许多不同的内容类型的响应(例如HTML、JSON、XML等)。
7)kernel.response
事件
典型的目的:修改响应
对象
内核的最终目标是转换请求
成一个响应
.的响应
时创建的kernel.request事件返回控制器,或由某个侦听器返回到kernel.view事件。
不管谁创建的响应
,另一事件-kernel.response
之后会被直接发送。此事件的典型侦听器将修改响应
对象的内容,例如修改标头、添加cookie,甚至更改响应
本身(例如,在结束之前注入一些JavaScript身体< / >
HTML响应的标签)。
在此事件被分派之后,最终的响应
对象返回的处理().在最典型的用例中,然后可以调用send ()方法,该方法发送标头并打印响应
内容。
kernel.response
在Symfonob娱乐下载y框架中
在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.
kernel.terminate
在Symfonob娱乐下载y框架中
如果你使用SwiftmailerBundle与Symfony一起使用ob娱乐下载内存
假脱机,然后EmailSenderListener激活,它实际上会发送您在请求期间计划发送的任何电子邮件。
异常处理:kernel.exception
事件
典型的目的:处理某种类型的异常并创建适当的响应
返回异常
如果在内部的任何位置抛出异常HttpKernel:处理()
,另一事件-kernel.exception
抛出。在内部,身体处理()
函数封装在try-catch块中。抛出任何异常时,kernel.exception
事件被分派,以便您的系统可以以某种方式响应异常。
向此事件的每个侦听器传递一个GetResponseForExceptionEvent对象,您可以使用该对象通过getException ()方法。此事件的典型侦听器将检查某种类型的异常并创建适当的错误响应
.
例如,要生成404页面,您可以抛出一个特殊类型的异常,然后在此事件上添加一个侦听器,该侦听器查找该异常并创建并返回404响应
.事实上,HttpKernel组件附带了一个ExceptionListener,如果您选择使用它,它将默认执行此操作和更多操作(有关详细信息,请参阅下面的侧栏)。
请注意
属性的响应时kernel.exception
事件时,传播停止。这意味着优先级较低的侦听器将不会被执行。
kernel.exception
在Symfonob娱乐下载y框架中
有两个主要的监听器kernel.exception
当使用Symfony框架时。ob娱乐下载
HttpKernel中的ExceptionListener
第一个是HttpKernel组件的核心,并被调用ExceptionListener.听众有几个目标:
- 抛出的异常被转换为FlattenException对象,其中包含关于请求的所有信息,但可以打印和序列化。
- 如果原始异常实现HttpExceptionInterface,然后
getStatusCode ()
而且getHeaders ()
异常时调用,并用于填充FlattenException
对象。这个想法是在创建最终响应时的下一步中使用这些。 - 执行控制器并传递扁平异常。要呈现的确切控制器作为构造函数参数传递给此侦听器。该控制器将返回final
响应
对于此错误页。
安全中的ExceptionListener
另一个重要的监听器是ExceptionListener.此侦听器的目标是处理安全异常,并且在适当时,帮助要进行身份验证的用户(例如重定向到登录页面)。
创建事件监听器
如您所见,您可以创建事件侦听器并将其附加到过程中分派的任何事件HttpKernel:处理()
周期。通常监听器是一个带有被执行方法的PHP类,但它可以是任何东西。有关创建和附加事件侦听器的详细信息,请参见EventDispatcher组件.
对象上的一个常量定义了每个“内核”事件的名称KernelEvents类。此外,每个事件侦听器都传递一个参数,该参数是类的某个子类KernelEvent.该对象包含关于系统当前状态的信息,每个事件都有自己的事件对象:
的名字 | KernelEvents 常数 |
参数传递给侦听器 |
---|---|---|
kernel.request | KernelEvents:请求 |
GetResponseEvent |
kernel.controller | KernelEvents:控制器 |
FilterControllerEvent |
kernel.view | KernelEvents:视图 |
GetResponseForControllerResultEvent |
kernel.response | KernelEvents:响应 |
FilterResponseEvent |
kernel.finish_request | KernelEvents: FINISH_REQUEST |
FinishRequestEvent |
kernel.terminate | KernelEvents:终止 |
PostResponseEvent |
kernel.exception | KernelEvents:异常 |
GetResponseForExceptionEvent |
一个完整的工作示例
使用HttpKernel组件时,您可以自由地将任何侦听器附加到核心事件,并使用实现HttpKernel的任何控制器解析器ControllerResolverInterface.然而,HttpKernel组件自带一些内置的监听器和一个内置的ControllerResolver,可以用来创建一个工作示例:
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
使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;使用ob娱乐下载\组件\HttpKernel\HttpKernel;使用ob娱乐下载\组件\EventDispatcher\EventDispatcher;使用ob娱乐下载\组件\HttpKernel\控制器\ControllerResolver;使用ob娱乐下载\组件\HttpKernel\EventListener\RouterListener;使用ob娱乐下载\组件\路由\RouteCollection;使用ob娱乐下载\组件\路由\路线;使用ob娱乐下载\组件\路由\匹配器\UrlMatcher;使用ob娱乐下载\组件\路由\RequestContext;$路线=新RouteCollection ();$路线->add (“你好”,新路线(“/ hello /{名称}”,数组(“_controller”= >函数(请求$请求){返回新响应(sprintf (“你好,% s”,$请求->get (“名字”)));}));$请求=请求::createFromGlobals ();$匹配器=新UrlMatcher ($路线,新RequestContext ());$调度程序=新EventDispatcher ();$调度程序->addSubscriber (新RouterListener ($匹配器));$解析器=新ControllerResolver ();$内核=新HttpKernel ($调度程序,$解析器);$响应=$内核->处理($请求);$响应->send ();$内核->终止($请求,$响应);
子请求
除了被发送到的main请求之外HttpKernel:处理()
,你也可以发送所谓的“分请求”。子请求的外观和行为与其他请求相似,但通常只用于呈现页面的一小部分,而不是整个页面。最常见的是从控制器发出子请求(或者从模板内部发出,由控制器渲染)。
要执行子请求,使用HttpKernel:处理()
,但将第二个参数更改如下:
12 3 4 5 6 7 8 9 10 11 12
使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpKernel\HttpKernelInterface;/ /……//根据需要手动创建一些其他请求$请求=新请求();//例如,可能手动设置它的_controller$请求->属性->集(“_controller”,“……”);$响应=$内核->处理($请求, HttpKernelInterface::SUB_REQUEST);//对这个响应执行一些操作
这创建了另一个完整的请求-响应周期,其中新的请求
被转化为响应
.内部唯一的区别是一些侦听器(例如安全)可能只对主请求起作用。的某个子类传递给每个侦听器KernelEvent,他的isMasterRequest ()可用于检查当前请求是“主”请求还是“子”请求。
例如,只需要对主请求起作用的侦听器可能是这样的:
1 2 3 4 5 6 7 8 9 10 11
使用ob娱乐下载\组件\HttpKernel\事件\GetResponseEvent;/ /……公共函数onKernelRequest(GetResponseEvent$事件){如果(!$事件->isMasterRequest ()) {返回;}/ /……}
定位资源
HttpKernel组件负责Symfony应用程序中使用的包机制。ob娱乐下载包的关键特性是它们允许覆盖应用程序使用的任何资源(配置文件、模板、控制器、翻译文件等)。
这种覆盖机制之所以有效,是因为资源不是通过它们的物理路径而是通过它们的逻辑路径引用的。例如,services . xml
文件存储在资源/ config /
AppBundle的目录被引用为@AppBundle /资源/配置/ services . xml
.当应用程序覆盖该文件时,即使您更改了AppBundle的目录,该逻辑路径也将工作。
HttpKernel组件提供了一个方法locateResource ()可用于将逻辑路径转换为物理路径:
1 2 3 4 5
使用ob娱乐下载\组件\HttpKernel\HttpKernel;/ /……$内核=新HttpKernel ($调度程序,$解析器);$路径=$内核->locateResource (“@AppBundle /资源/配置/ services . xml”);