HttpKernel组件

欧宝娱乐app下载地址Symfony 5.3支持经过JoliCode

HttpKernel组件

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

安装

1
$Composer需要Symfony欧宝娱乐app下载地址 / HTTP-Kernel

笔记

如果在Symfony应用程序之外安装此组件,则必须要求欧宝娱乐app下载地址供应商/ autoload.php.文件,以启用Composer提供的类自动加载机制。阅读这篇文章为更多的细节。

请求的工作流

也可以看看

本文介绍如何在任何PHP应用程序中使用HttpKernel功能作为独立组件。在Sy欧宝娱乐app下载地址mfony应用程序中,所有内容都已配置并准备使用。阅读控制器活动和活动听众文章了解如何使用它在Symfony应用程序中创建控制器和定义事件。欧宝娱乐app下载地址

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

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

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

名称空间欧宝娱乐app下载地址Symfony \ \ HttpKernel组件;使用欧宝娱乐app下载地址Symfony\Component\HttpFoundation\Request;接口HttpKernelInterface{/ /……/***@returnresponse一个响应实例*/公共函数处理请求美元的请求int$type=自己::MAIN_REQUEST保龄球抓住美元=真正的);}

内部,,HttpKernel:处理()- 具体实施HttpKernelInterface:处理()-定义一个以欧宝娱乐app下载地址Symfony\Component\HttpFoundation\Request以a结尾欧宝娱乐app下载地址symfony \ component \ httpfoundation \ response

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

httpkernel:由事件驱动

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

为了帮助解释这个过程,本文档查看了这个过程的每个步骤,并讨论了HttpKernel的一个特定实现——Symfony框架——是如何工作的。欧宝娱乐app下载地址

最初,使用欧宝娱乐app下载地址symfony \ component \ httpkernel \ httpkernel不需要很多步骤。你创建一个活动调度员和一个控制器和参数解析器(解释如下)。要完成工作内核,您将向下面讨论的事件添加更多事件侦听器:

使用欧宝娱乐app下载地址Symfony \ \ EventDispatcher \ EventDispatcher组件;使用欧宝娱乐app下载地址Symfony\Component\HttpFoundation\Request;使用欧宝娱乐app下载地址symfony \ component \ httpfoundation \ lequencystack;使用欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ ArgumentResolver控制器;使用欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ ControllerResolver控制器;使用欧宝娱乐app下载地址symfony \ component \ httpkernel \ httpkernel;//创建Request对象美元的请求=请求::createfromglobals.();美元的调度员=EventDispatcher();// ...添加一些活动侦听器//创建控制器和参数解析器controllerResolver美元=ControllerResolver();argumentResolver美元=ArgumentResolver();//初始化内核美元的内核=HttpKernel美元的调度员controllerResolver美元请求栈(),argumentResolver美元);//实际执行内核,将请求转换为响应//通过调度事件、调用控制器并返回响应美元的反应=美元的内核->处理美元的请求);//发送头文件并返回内容美元的反应->发送();//触发内核。终止事件美元的内核->终止美元的请求美元的反应);

见“完整的工作示例更具体的实施。

有关将侦听器添加到下面的事件的一般信息,请参阅创建事件监听器

小心

从3.1开始欧宝娱乐app下载地址symfony \ component \ httpkernel \ httpkernel接受第四个参数,它必须是的实例欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ ArgumentResolverInterface控制器.在4.0中,此论点将成为强制性的。

也可以看看

关于使用HttpKernel组件和其他Symfony组件创建自己的框架,有一个精彩的教程系列。看见欧宝娱乐app下载地址介绍

1)kernel.request事件

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

内核事件信息表

在内部分派的第一个事件httpkernel ::句柄kernel.request,可能有各种不同的侦听器。

这一事件的听众可能多种多样。某些侦听器(如安全侦听器)可能有足够的信息来创建响应例如,如果安全侦听器确定用户没有访问权限,则该侦听器可能会返回欧宝娱乐app下载地址Symfony\Component\HttpFoundation\RedirectResponse登录页面或403访问拒绝响应。

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

其他侦听器初始化事物或向请求添加更多信息。例如,侦听器可能会确定并设置区域设置请求目的。

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

总的来说,目的是kernel.request事件要么要创建并返回一个响应直接,或将信息添加到请求(例如,设置区域设置或在请求属性)。

笔记

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

2)解决控制器

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

如何您确定请求的确切控制器完全取决于您的应用程序。这是“控制器解析器”的工作,该类实现欧宝娱乐app下载地址Symfony\Component\HttpKernel\Controller\ControllerResolverInterface是的构造函数参数之一HttpKernel

你的工作是创建一个实现接口的类,并填充它的方法:getController ().实际上,已经存在一个默认实现,您可以直接使用或从中学习:欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ ControllerResolver控制器。下面的侧栏将详细说明此实现:

名称空间欧宝娱乐app下载地址Symfony \ \ HttpKernel \ Controller组件;使用欧宝娱乐app下载地址Symfony\Component\HttpFoundation\Request;接口控制器ResolverInterface{公共函数getController请求美元的请求);}

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

3)内核控制器事件

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

内核事件信息表

确定控制器可调用对象后,HttpKernel:处理()派遣内核控制器事件。此事件的侦听器可能会初始化系统的某些部分,这些部分在确定某些事项(例如控制器、路由信息)后但在执行控制器之前需要初始化。有关一些示例,请参阅下面的Symfony部分。欧宝娱乐app下载地址

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

4)获取控制器参数

下一个HttpKernel:处理()呼叫ArgumentResolverInterface :: getarguments().记住控制器返回getController ()是一个可调用的。的目的getArguments ()是返回应该传递给该控制器的参数数组。具体如何做到这一点完全取决于您的设计,尽管内置欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ ArgumentResolver控制器是一个很好的例子。

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

5)调用控制器

下一个步骤HttpKernel:处理()确实正在执行控制器。

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

通常,控制器将返回a响应目的。如果这是真的,那么内核的工作就是这样做!在这种情况下,下一步是kernel.response事件。

但是如果控制器返回除了a之外的任何东西响应,那么内核就有更多的工作要做kernel.view(由于最终目标是总是产生响应对象)。

笔记

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

6)kernel.view事件

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

内核事件信息表

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

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

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

笔记

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

7)kernel.response事件

典型的目的:修改响应对象在它被发送之前

内核事件信息表

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

无论谁创造了响应,另一个事件kernel.response之后直接发送。此事件的典型侦听器将修改响应对象的某些方法,例如修改头文件、添加cookie,甚至更改响应本身(例如,在结束前注入一些JavaScriptHTML响应的标签)。

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

8)kernel.terminate事件

典型的目的:在响应已流过用户后执行一些“重”行动

内核事件信息表

HttpKernel进程的最后一个事件是kernel.terminate而且是独一无二的,因为它发生了HttpKernel:处理()方法,并将响应发送给用户后。从上面召回,然后使用内核的代码,如下所示:

//发送头文件并返回内容美元的反应->发送();//触发内核。终止事件美元的内核->终止美元的请求美元的反应);

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

小心

在内部,httpkernel利用了fastcgi_finish_requestPHP函数。这意味着此刻,只有PHP FPM当服务器的PHP进程仍在执行某些任务时,服务器API能够向客户端发送响应。对于所有其他服务器API,侦听器kernel.terminate仍在执行,但在全部完成之前,不会将响应发送到客户端。

笔记

使用kernel.terminate事件是可选的,只有在内核实现时才应该调用欧宝娱乐app下载地址Symfony\Component\HttpKernel\TerminableInterface

处理异常:kernel.exception.事件

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

内核事件信息表

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

向每个此事件的侦听器传递一个欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ ExceptionEvent事件对象,可以使用该对象通过getThrowable()方法。此事件上的典型监听器将检查某种类型的异常并创建适当的错误响应

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

笔记

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

创建事件监听器

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

控件上的每个“内核”事件的名称都定义为常量欧宝娱乐app下载地址Symfony \ \ HttpKernel \ KernelEvents组件班级。此外,每个事件侦听器都传递了一个参数,这是一些子类欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ KernelEvent事件.此对象包含有关系统当前状态的信息,每个事件都有自己的事件对象:

的名字 KernelEvents常数 参数传递给侦听器
kernel.request KernelEvents:请求 欧宝娱乐app下载地址Symfony RequestEvent \ HttpKernel \事件\ \组件
内核控制器 KernelEvents:控制器 欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ ControllerEvent事件
kernel.controller_参数 内科特:: Controller_Arguments. 欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ ControllerArgumentsEvent事件
kernel.view KernelEvents:视图 欧宝娱乐app下载地址Symfony\Component\HttpKernel\Event\ViewEvent
kernel.response KernelEvents:响应 欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ ResponseEvent事件
kernel.finish_request KernelEvents: FINISH_REQUEST 欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ FinishRequestEvent事件
kernel.terminate KernelEvents:终止 欧宝娱乐app下载地址Symfony\Component\HttpKernel\Event\TerminateEvent
kernel.exception. KernelEvents:异常 欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ ExceptionEvent事件

完整的工作示例

当使用HttpKernel组件时,您可以自由地将任何监听器附加到核心事件,使用实现欧宝娱乐app下载地址Symfony\Component\HttpKernel\Controller\ControllerResolverInterface并使用实现欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ ArgumentResolverInterface控制器.但是,HttpKernel组件附带了一些内置侦听器,以及其他可用于创建工作示例的其他内容:

使用欧宝娱乐app下载地址Symfony \ \ EventDispatcher \ EventDispatcher组件;使用欧宝娱乐app下载地址Symfony\Component\HttpFoundation\Request;使用欧宝娱乐app下载地址symfony \ component \ httpfoundation \ lequencystack;使用欧宝娱乐app下载地址symfony \ component \ httpfoundation \ response;使用欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ ArgumentResolver控制器;使用欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ ControllerResolver控制器;使用欧宝娱乐app下载地址Symfony \ \ HttpKernel \ EventListener \ RouterListener组件;使用欧宝娱乐app下载地址symfony \ component \ httpkernel \ httpkernel;使用欧宝娱乐app下载地址Symfony \组件\ \匹配器\ UrlMatcher路由;使用欧宝娱乐app下载地址Symfony \ \路由\ RequestContext组件;使用欧宝娱乐app下载地址Symfony \组件\路由\路线;使用欧宝娱乐app下载地址Symfony \ Component \ Routing \ Routecollection;美元的路线=RouteCollection();美元的路线->添加“你好”路线“/ hello /{名称}”[“_controller”=>函数请求美元的请求{返回响应Sprintf.“你好,% s”美元的请求->得到“名字”)));}]));美元的请求=请求::createfromglobals.();美元的匹配器=UrlMatcher美元的路线RequestContext());美元的调度员=EventDispatcher();美元的调度员->添加订户RouterListener.美元的匹配器请求栈()));controllerResolver美元=ControllerResolver();argumentResolver美元=ArgumentResolver();美元的内核=HttpKernel美元的调度员controllerResolver美元请求栈(),argumentResolver美元);美元的反应=美元的内核->处理美元的请求);美元的反应->发送();美元的内核->终止美元的请求美元的反应);

子请求

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

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

使用欧宝娱乐app下载地址Symfony\Component\HttpFoundation\Request;使用欧宝娱乐app下载地址Symfony \ \ HttpKernel \ HttpKernelInterface组件;/ /……//根据需要手动创建一些其他请求美元的请求=请求();//例如,可能手动设置其_controller美元的请求->属性->“_controller”“……”);美元的反应=美元的内核->处理美元的请求HttpKernelInterface::分包请求);//对这个反应做点什么

这将创建另一个完整的请求-响应周期,其中请求转化为响应.内部唯一的区别是一些侦听器(例如安全)可能只对主请求起作用。每个侦听器被传递给欧宝娱乐app下载地址Symfony \组件\ HttpKernel \ \ KernelEvent事件,他的isMainRequest ()可以用来检查当前请求是“主”请求还是“子”请求。

例如,只需要对主请求进行操作的侦听器可能看起来像这样:

使用欧宝娱乐app下载地址Symfony RequestEvent \ HttpKernel \事件\ \组件;/ /……公共函数onKernelRequest请求事件美元的事件{如果!!美元的事件->伊斯曼请求()){返回;}/ /……}

寻找资源

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

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

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

$途径=美元的内核->locateResource“@FooBundle /资源/配置/ services . xml”);

这个工作,包括代码示例,是根据知识共享BY-SA 3.0执照。