HttpKernel组件:HttpKernel类

编辑本页

警告:您正在浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 4.0,现已不再维护。

本页的更新版本用于Sy欧宝娱乐app下载地址mfony 6.2(当前稳定版本)。

HttpKernel组件:HttpKernel类

如果您现在要使用我们的框架,您可能必须添加对自定义错误消息的支持。我们确实有404和500错误支持,但响应是硬编码在框架本身。不过,使它们可定制非常简单:分派一个新事件并监听它。正确地执行它意味着侦听器必须调用常规控制器。但是如果错误控制器抛出异常怎么办?你会陷入一个无限循环。应该有更简单的方法,对吧?

进入HttpKernel类。而不是一遍又一遍地解决同样的问题,而不是每次都重新发明轮子HttpKernel类的通用、可扩展和灵活实现HttpKernelInterface

这个类与我们迄今为止编写的框架类非常相似:它在处理请求期间在某些战略点分派事件,它使用控制器解析器来选择要将请求分派到的控制器,作为额外的奖励,它会处理边缘情况,并在出现问题时提供良好的反馈。

下面是新的框架代码:

1 2 3 4 5 6 7 8
/ / example.com/src/Simplex/Framework.php名称空间单纯形使用欧宝娱乐app下载地址组件HttpKernelHttpKernel框架扩展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
/ / example.com/web/front.phprequire_once__DIR__“/ . . /供应商/ autoload.php”使用欧宝娱乐app下载地址组件EventDispatcherEventDispatcher使用欧宝娱乐app下载地址组件HttpFoundation请求使用欧宝娱乐app下载地址组件HttpFoundationRequestStack使用欧宝娱乐app下载地址组件HttpFoundation响应使用欧宝娱乐app下载地址组件HttpKernel使用欧宝娱乐app下载地址组件路由请求=请求::createFromGlobals ();requestStackRequestStack ();路线包括__DIR__“/ . . / src / app.php”上下文路由\ RequestContext ();匹配器路由\匹配器\ UrlMatcher (路线上下文);controllerResolverHttpKernel \控制器\ ControllerResolver ();argumentResolverHttpKernel \控制器\ ArgumentResolver ();调度程序EventDispatcher ();调度程序->addSubscriber (HttpKernel \ EventListener \ RouterListener (匹配器requestStack));框架单纯形\框架(调度程序controllerResolverrequestStackargumentResolver);响应框架->处理(请求);响应->send ();

RouterListener是我们在框架中使用的相同逻辑的实现:它匹配传入请求并使用路由参数填充请求属性。

现在,我们的代码比以往任何时候都更简洁、更健壮、更强大。例如,使用内置的ExceptionListener要使错误管理可配置:

1 2 3 4 5 6
errorHandler函数组欧宝娱乐app下载地址件(Symfony \ \调试\ \ FlattenException异常异常味精“出事了!”('异常->getMessage()。“)”返回响应(味精异常->getStatusCode ());};调度程序->addSubscriber (HttpKernel \ EventListener \ ExceptionListener (errorHandler));

ExceptionListener给你一个FlattenException实例,而不是抛出异常实例来简化异常操作和显示。它可以接受任何有效的控制器作为异常处理程序,所以你可以创建一个ErrorController类,而不是使用闭包:

1 2 3 4
侦听器HttpKernel \ EventListener \ ExceptionListener (“日历\控制器\ ErrorController:异常”);调度程序->addSubscriber (侦听器);

错误控制器如下所示:

12 3 4 5 6 7 8 9 10 11 12 13 14 15
/ / example.com/src/Calendar/Controller/ErrorController.php名称空间日历控制器使用欧宝娱乐app下载地址组件HttpFoundation响应使用欧宝娱乐app下载地址组件调试异常FlattenExceptionErrorController公共函数异常(FlattenException异常味精“出事了!”('异常->getMessage()。“)”返回响应(味精异常->getStatusCode ());}}

瞧!简单且可定制的错误管理。当然,如果你的控制器抛出一个异常,HttpKernel会很好地处理它。

在第二章中,我们讨论了回应::准备()方法,该方法确保响应与HTTP规范兼容。在将Response发送给客户端之前调用它可能是个好主意;这就是ResponseListener:

1
调度程序->addSubscriber (HttpKernel \ EventListener \ ResponseListener (“utf - 8”));

这个也很简单!让我们再来看看另一个问题:您是否希望对流响应提供开箱即用的支持?只要订阅StreamedResponseListener

1
调度程序->addSubscriber (HttpKernel \ EventListener \ StreamedResponseListener ());

在控制器中,返回aStreamedResponse实例,而不是响应实例。

提示

读了内置Symfony欧宝娱乐app下载地址事件参考了解更多关于HttpKernel分派的事件以及它们如何允许你改变请求流的信息。

现在,让我们创建一个监听器,它允许控制器返回一个字符串,而不是一个完整的Response对象:

12 3 4 5 6 7 8 9 10 11 12
LeapYearController公共函数指数(请求请求一年leapYearLeapYear ();如果leapYear->isLeapYear (一年)) {返回“是的,今年是闰年!”;}返回“不,今年不是闰年。”;}}

为了实现这个特性,我们将侦听kernel.view事件,该事件在控制器被调用后被触发。它的目标是将控制器返回值转换为适当的Response实例,但仅在需要时:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/ / example.com/src/Simplex/StringResponseListener.php名称空间单纯形使用欧宝娱乐app下载地址组件EventDispatcherEventSubscriberInterface使用欧宝娱乐app下载地址组件HttpKernel事件GetResponseForControllerResultEvent使用欧宝娱乐app下载地址组件HttpFoundation响应StringResponseListener实现了EventSubscriberInterface公共函数onView(GetResponseForControllerResultEvent事件响应事件->getControllerResult ();如果(is_string (响应)) {事件->setResponse (响应(响应));}}公共静态函数getSubscribedEvents()返回数组“kernel.view”= >“onView”);}}

代码很简单,因为kernel.view事件只有在控制器返回值不是Response时才会触发,因为在事件上设置响应会停止事件传播(我们的侦听器不能干扰其他视图侦听器)。

不要忘记在前端控制器中注册它:

1
调度程序->addSubscriber (单纯形\ StringResponseListener ());

请注意

如果你忘记注册订阅者,HttpKernel会抛出一个异常,并附上一条漂亮的消息:控制器必须返回一个响应(不,这不是闰年。鉴于)。

在这一点上,我们的整个框架代码是尽可能紧凑的,它主要由现有库的程序集组成。扩展是一个注册事件监听器/订阅者的问题。

希望您现在已经更好地理解了为什么使用简单的外观HttpKernelInterface是如此强大。它的默认实现,HttpKernel,为您提供了许多很酷的功能,随时可以开箱即用,无需任何努力。因为HttpKernel实际上是驱动Symfony和Silex框架的代码,所以你拥有了两个世界的优点:一个自定义的框架,欧宝娱乐app下载地址根据你的需要量身定制,但基于一个被证明适用于许多网站的坚如磐石和良好维护的底层架构;经过安全问题审计的代码,并已被证明具有良好的可伸缩性。

此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。